gtk-css-engine r4 - in bzr-playground: . libccd libccd/ccd libccd/doc libccd/examples src themes themes/gtk-css-test themes/gtk-css-test/gtk-2.0
- From: robsta svn gnome org
- To: svn-commits-list gnome org
- Subject: gtk-css-engine r4 - in bzr-playground: . libccd libccd/ccd libccd/doc libccd/examples src themes themes/gtk-css-test themes/gtk-css-test/gtk-2.0
- Date: Mon, 18 Aug 2008 13:50:33 +0000 (UTC)
Author: robsta
Date: Mon Aug 18 13:50:33 2008
New Revision: 4
URL: http://svn.gnome.org/viewvc/gtk-css-engine?rev=4&view=rev
Log:
Initial import.
Added:
bzr-playground/ (props changed)
bzr-playground/AUTHORS
bzr-playground/COPYING
bzr-playground/ChangeLog
bzr-playground/HACKING
bzr-playground/MAINTAINERS
bzr-playground/Makefile.am
bzr-playground/NEWS
bzr-playground/README
bzr-playground/TODO
bzr-playground/autogen.sh (contents, props changed)
bzr-playground/configure.in
bzr-playground/libccd/
bzr-playground/libccd/Makefile.am
bzr-playground/libccd/ccd/
bzr-playground/libccd/ccd/Makefile.am
bzr-playground/libccd/ccd/ccd-background.c
bzr-playground/libccd/ccd/ccd-background.h
bzr-playground/libccd/ccd/ccd-block.c
bzr-playground/libccd/ccd/ccd-block.h
bzr-playground/libccd/ccd/ccd-border.c
bzr-playground/libccd/ccd/ccd-border.h
bzr-playground/libccd/ccd/ccd-color.c
bzr-playground/libccd/ccd/ccd-color.h
bzr-playground/libccd/ccd/ccd-features.h.in
bzr-playground/libccd/ccd/ccd-gtk-style.c
bzr-playground/libccd/ccd/ccd-gtk-style.h
bzr-playground/libccd/ccd/ccd-image.c
bzr-playground/libccd/ccd/ccd-image.h
bzr-playground/libccd/ccd/ccd-node.c
bzr-playground/libccd/ccd/ccd-node.h
bzr-playground/libccd/ccd/ccd-parser.c
bzr-playground/libccd/ccd/ccd-parser.h
bzr-playground/libccd/ccd/ccd-property.c
bzr-playground/libccd/ccd/ccd-property.h
bzr-playground/libccd/ccd/ccd-selector-group-priv.h
bzr-playground/libccd/ccd/ccd-selector-group.c
bzr-playground/libccd/ccd/ccd-selector-group.h
bzr-playground/libccd/ccd/ccd-selector.c
bzr-playground/libccd/ccd/ccd-selector.h
bzr-playground/libccd/ccd/ccd-style.c
bzr-playground/libccd/ccd/ccd-style.h
bzr-playground/libccd/ccd/ccd-stylesheet.c
bzr-playground/libccd/ccd/ccd-stylesheet.h
bzr-playground/libccd/ccd/ccd-utils.h
bzr-playground/libccd/ccd/ccd.c
bzr-playground/libccd/ccd/ccd.h
bzr-playground/libccd/doc/
bzr-playground/libccd/doc/Makefile.am
bzr-playground/libccd/doc/ccd-docs.sgml
bzr-playground/libccd/doc/ccd-sections.txt
bzr-playground/libccd/doc/version.xml.in
bzr-playground/libccd/examples/
bzr-playground/libccd/examples/Makefile.am
bzr-playground/libccd/examples/example1.c
bzr-playground/libccd/examples/example1.css
bzr-playground/libccd/examples/internal.c
bzr-playground/src/
bzr-playground/src/Makefile.am
bzr-playground/src/gce-maps.c
bzr-playground/src/gce-maps.h
bzr-playground/src/gce-rc-style.c
bzr-playground/src/gce-rc-style.h
bzr-playground/src/gce-style.c
bzr-playground/src/gce-style.h
bzr-playground/src/gce-theme.c
bzr-playground/themes/
bzr-playground/themes/Makefile.am
bzr-playground/themes/gtk-css-test/
bzr-playground/themes/gtk-css-test/Makefile.am
bzr-playground/themes/gtk-css-test/gtk-2.0/
bzr-playground/themes/gtk-css-test/gtk-2.0/Makefile.am
bzr-playground/themes/gtk-css-test/gtk-2.0/gtkrc
bzr-playground/themes/gtk-css-test/gtk-2.0/styles.css
Added: bzr-playground/AUTHORS
==============================================================================
--- (empty file)
+++ bzr-playground/AUTHORS Mon Aug 18 13:50:33 2008
@@ -0,0 +1 @@
+Robert Staudinger <robsta gnome org>
Added: bzr-playground/COPYING
==============================================================================
--- (empty file)
+++ bzr-playground/COPYING Mon Aug 18 13:50:33 2008
@@ -0,0 +1,502 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
Added: bzr-playground/HACKING
==============================================================================
--- (empty file)
+++ bzr-playground/HACKING Mon Aug 18 13:50:33 2008
@@ -0,0 +1,45 @@
+
+HACKING
+=======
+
+General remarks
+---------------
+
+* Code is a maximum of 80 characters wide. This keeps it readable also where
+ the original screen width limitations do not apply any more.
+
+* Use C99, in particular stdint and stdbool, except that variables go at the
+ beginning of the block. You may use embedded counters in `for' loops though.
+
+* Do not initialise variables, pointers in particular, where they are declared.
+ Initialise immediately before usage and read compiler warnings to find out
+ whether any variables are being used without initialisation.
+
+* Use variable names in `sizeof()' statements rather than type names. Otherwise
+ refactorings including changing the datatype can render those broken. Example:
+
+ foo_t *f;
+ memset (f, 0, sizeof (*f));
+
+Including files
+---------------
+
+* Always include files in the following order:
+ (1) C headers, in alphabetical order.
+ (2) Dependency libraries' headers, in alphabetical order.
+ (3) Project headers, in alphabetical order.
+
+* In header files only ever include using pointy brackets and directory prefix.
+ This makes sure that installed headers work correctly and facilitates
+ installation of multiple incompatible library versions in the same prefix.
+ Example foo.h:
+
+ #include <bar/bar.h>
+
+ In C files plain inclusion of headers from the project is encouraged, just
+ give the header's file name and leave setting of directories to the build
+ system. Example foo.c:
+
+ #include "foo.h"
+
+
Added: bzr-playground/MAINTAINERS
==============================================================================
--- (empty file)
+++ bzr-playground/MAINTAINERS Mon Aug 18 13:50:33 2008
@@ -0,0 +1,4 @@
+Robert Staudinger
+E-mail: robsta gnome org
+Userid: robsta
+
Added: bzr-playground/Makefile.am
==============================================================================
--- (empty file)
+++ bzr-playground/Makefile.am Mon Aug 18 13:50:33 2008
@@ -0,0 +1,19 @@
+
+ACLOCAL_AMFLAGS = -I .
+DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
+
+SUBDIRS = libccd src themes
+
+EXTRA_DIST = \
+ AUTHORS \
+ ChangeLog \
+ COPYING \
+ INSTALL \
+ MAINTAINERS \
+ NEWS \
+ README \
+ autogen.sh
+
+distclean-local:
+ rm -rf *.cache *~
+
Added: bzr-playground/NEWS
==============================================================================
Added: bzr-playground/README
==============================================================================
--- (empty file)
+++ bzr-playground/README Mon Aug 18 13:50:33 2008
@@ -0,0 +1,211 @@
+
+CSS Theme Engine for GTK+
+=========================
+
+Putting stuff together for a gtk theme engine that would be configured using CSS rather than gtkrc syntax.
+
+Bzr repository at:
+ http://www.gnome.org/~robsta/bzr/gtk-css-engine/
+ bzr+ssh://bzr-playground.gnome.org/bzr/robsta/gtk-css-engine
+
+Previously available from:
+ sftp://robsta window gnome org/home/users/robsta/public_html/bzr/gtk-css-engine/
+
+Primitives
+----------
+
+Attributes are canonicalised, i.e. s/_/-/g.
+Comments are enclosed in ().
+Optionality is expressed through [].
+pseudo class "normal" will be default.
+
+* hline
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - detail: NULL | handlebox | hseparator | menuitem | tearoffmenuitem | toolbar
+
+* vline
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - detail: NULL | handlebox | toolbar | vseparator
+
+* shadow
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - shadow: none | in | out | etched-in | etched-out
+ - detail: NULL | calendar | combobox | dnd | entry | frame | handle |
+ scrolled-window | text | viewport
+
+* arrow
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - shadow: none | in | out | etched-in | etched-out
+ - arrow: up | down | left | right | none
+ - detail: NULL | arrow | calendar | menu-scroll-arrow-up | menu-scroll-arrow-down |
+ menuitem | notebook | spinbutton | tearoffmenuitem |
+ hscrollbar | vscrollbar
+
+* diamond
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - shadow: none | in | out | etched-in | etched-out
+ - No predefined detail strings for `diamond'.
+
+* DEPRECATED: string
+
+* box
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - shadow: none | in | out | etched-in | etched-out
+ - detail: NULL | buttondefault | button | bar (cellrendererprogress) |
+ handlebox-bin | hruler | hseparator (in `wide-separators' mode) |
+ menubar | menu | menu-scroll-arrow-up | menu-scroll-arrow-down |
+ menuitem | hseparator | notebook | optionmenu |
+ bar (progress-bar) | trough (progress-bar | range) | hscrollbar |
+ vscrollbar | trough-upper | trough-lower | trough-fill-level-full |
+ trough-fill-level | spinbutton | spinbutton-up | spinbutton-down |
+ toolbar | vseparator | vruler | base (window)
+
+* flat-box
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - shadow: none | in | out | etched-in | etched-out
+ - detail: NULL | checkbutton | curve-bg | entry-bg | eventbox | expander | tooltip |
+ listitem | trough (progress) | checkbutton | text | treeitem |
+ viewportbin | base (window) |
+ cell-odd[-start | -end | -middle] |
+ cell-even[-start | -end | -middle] |
+ cell-odd-ruled-sorted[-start | -end | -middle] |
+ cell-even-ruled-sorted[-start | -end | -middle] |
+ cell-odd-ruled[-start | -end | -middle] |
+ cell-even-ruled[-start | -end | -middle] |
+ cell-odd-sorted[-start | -end | -middle] |
+ cell-even-sorted[-start | -end | -middle]
+
+* check
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - shadow: none | in | out | etched-in | etched-out
+ - detail: NULL | cellcheck | checkbutton | check (menuitem)
+
+* option
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - shadow: none | in | out | etched-in | etched-out
+ - detail: NULL | cellradio | option (menuitem) | radiobutton
+
+* tab
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - shadow: none | in | out | etched-in | etched-out
+ - detail: NULL | optionmenutab
+
+* extension
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - shadow: none | in | out | etched-in | etched-out
+ - position: left | right | top | bottom
+ - detail: NULL | tab (notebook)
+
+* focus
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - detail: NULL | button | calendar-day | checkbutton | entry | expander |
+ colorwheel-light | colorwheel-dark | iconview-drop-indicator |
+ icon-view | add-mode (listitem) | tab | button (gtkoptionmenu) |
+ trough (gtkrange) | text | textview | tray-icon | treeitem |
+ treeview-drop-indicator[-left | -right | -middle] |
+ treeview[-left | -right | -middle]
+
+* slider
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - shadow: none | in | out | etched-in | etched-out
+ - detail: NULL | hscale | vscale
+
+* handle
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - shadow: none | in | out | etched-in | etched-out
+ - orientation: horizontal | vertical
+ - detail: NULL | handlebox | paned
+
+* expander
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - style: collapsed | semi-collapsed | semi-expanded | expanded
+ - detail: NULL | expander | treeview
+
+* layout
+ Styling of text will not be considered for now.
+
+* resize-grip
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - edge: north-west | north | north-east | west | east | south-west | south | south-east
+ - detail: NULL | statusbar
+
+* shadow-gap
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - shadow: none | in | out | etched-in | etched-out
+ - position: left | right | top | bottom
+ - detail: NULL | frame
+
+* box-gap
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - shadow: none | in | out | etched-in | etched-out
+ - position: left | right | top | bottom
+ - detail: NULL | notebook
+
+* polygon
+ Pseudo classes: normal | active | prelight | selected | insensitive
+ Selectors:
+ - Arbitrary widget properties that can be represented as a string.
+ - shadow: none | in | out | etched-in | etched-out
+
+Widgets
+-------
+
+Support for widgets will probably be implemented by aliases on primitives, e.g. GtkButton might be matched to "box[class=GtkButton]" internally.
+
+The widget's name property is special cased and used as ID, thus it can be matched by '#foo { ... }'.
+
+
+Composite Widgets
+-----------------
+
+Composite widgets will probably be supported through selectors, e.g. "GtkComboBoxEntry > GtkEntry" (child selector) or "GtkComboBoxEntry GtkEntry" (descendant selector).
+
+
+Brainstorming
+-------------
+
+* Should the detail string act as a counterpart to what `class' is in html? Then one could write "hline.toolbar { color: black; }".
+
+* Multiple classes per element, a la <a class="foo bar baz">. Does this buy anything? Could possibly be matched on the widget name.
+
+* Application matching, possibly something like "application#gimp { ... }", match on g_get_prgname(). This could probably also be done with a custom `@' rule, e.g. "@application gimp { stylesheet goes here }"
+
+* CSS Variables ( http://disruptive-innovations.com/zoo/cssvariables/ ). Named colours could be implemented as built-in variables.
+
+* Easy to use when faking the gtk style (firefox, openoffice). We can provide custom hierarchy matching through a proxy in ccd.
Added: bzr-playground/TODO
==============================================================================
--- (empty file)
+++ bzr-playground/TODO Mon Aug 18 13:50:33 2008
@@ -0,0 +1,95 @@
+
+TODO
+====
+
+0.1 "Infrastructure"
+--------------------
+
+* Matching.
+* Background color.
+* Basic border styles.
+* Single background image, repeating, tiling.
+* Prototypical default theme.
+* Bugzilla module.
+
+Code review:
+ + Check all list iterators for const-ness.
+ + Make all string comparisons case insensitive?
+ + Get rid of the _match() functions all toghether?
+ + Check 80 column code width.
+
+0.2 "Correctness"
+-----------------
+
+* Border images.
+* Unit tests.
+* Test using the theme torturer.
+* Test using valgrind.
+
+0.3 "Features"
+--------------
+
+* Multiple background images.
+* Additional border features, e.g. `collapsed', `none'.
+* Implement `inherit' as per CSS spec. Do we need our own set of attributed
+ inherited by default?
+* Support per-object style attributes in libccd (and maybe also the engine, but how?).
+ The node-class interface would have to be extended to support a `get_style()'
+ method.
+* Application-specific theming, someting like "@import "gimp.css" gimp;".
+
+0.4 "Performance"
+-----------------
+
+* Profile using the theme torturer.
+* Can selectors and blocks be merged at theme load time?
+* Can computed styles be attached to widgets using g_object_set_data()?
+* Use a string pool for the lookup tables?
+* Can we use binary search in the lookup tables?
+* Cache the type name inside the node?
+* Implement "is_a(ccd_node_t *node, char const *type_name)" rather than
+ recursing base types manually?
+
+0.5 "Compliance"
+----------------
+
+* Support widget mimicking by creating Gtk[Rc]Style style information and
+ feeding it back into gtk, e.g. using gtk_rc_parse(). Maybe we would end up
+ with two drawing modes, the `normal' one and the GtkStyle based one. In any
+ case gtk_rc_get_style_by_paths() should work.
+
+More 0. releases go here if needed ...
+
+1.0 "Rejoicing"
+---------------
+
+* Implement additional CSS pseudo classes like ":first", ":last", ":top",
+ ":bottom". Those will be queried on the container and can e.g. be used to
+ make the outer corners of buttons in a button box rounded.
+
+ GtkHButtonBox GtkButton:first {
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+ }
+ GtkHButtonBox GtkButton:last {
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+ }
+
+1.2 "Fonts"
+-----------
+
+* Implement font effects.
+
+2.0 "Canvas"
+------------
+
+* Implement a WHATWG canvas and let the theme draw on it using ECMAScript.
+
+Out of band
+-----------
+
+* Create a spiffy website, possibly on http://gnome.org/projects.
+ Any volunteers?
+* Evaluate alternative SVG renderers as they become available.
+
Added: bzr-playground/autogen.sh
==============================================================================
--- (empty file)
+++ bzr-playground/autogen.sh Mon Aug 18 13:50:33 2008
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+olddir=`pwd`
+cd $srcdir
+
+(gtkdocize --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "You must have gtk-doc installed to compile ."
+ echo "Install the appropriate package for your distribution,"
+ echo "or get the source tarball at http://ftp.gnome.org/pub/GNOME/sources/gtk-doc/"
+ DIE=1
+}
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "You must have autoconf installed to compile $PROJECT."
+ echo "Install the appropriate package for your distribution,"
+ echo "or get the source tarball at http://ftp.gnu.org/gnu/autoconf/"
+ DIE=1
+}
+
+if test "$DIE" = "1"; then
+ exit 1
+fi
+
+gtkdocize || exit $?
+autoreconf --force --install --symlink || exit $?
+
+cd $olddir
+
+conf_flags="--enable-maintainer-mode"
+
+if test x$NOCONFIGURE = x; then
+ echo Running $srcdir/configure $conf_flags "$@" ...
+ $srcdir/configure $conf_flags "$@" \
+ && echo Now type \`make\' to compile. || exit 1
+else
+ echo Skipping configure process.
+fi
+
Added: bzr-playground/configure.in
==============================================================================
--- (empty file)
+++ bzr-playground/configure.in Mon Aug 18 13:50:33 2008
@@ -0,0 +1,91 @@
+
+AC_PREREQ(2.61)
+AC_INIT([gtk-css-engine], [0.1])
+AC_CONFIG_SRCDIR([config.h.in])
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_HEADERS([libccd/ccd/ccd-features.h])
+
+AM_INIT_AUTOMAKE
+AM_MAINTAINER_MODE
+
+### Checks for configure arguments
+
+AC_ARG_ENABLE([debug],
+ [AS_HELP_STRING([--enable-debug], [enable debug code])],
+[
+ if test "$enableval" == "yes"; then
+ AC_DEFINE([CCD_DEBUG], [1], [Enable debug code])
+ fi
+])
+
+### Checks for programs.
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+
+# gtk-doc
+gtk_doc_installed=true
+#ifdef([GTK_DOC_CHECK],[GTK_DOC_CHECK([1.0])],[gtk_doc_installed=false])
+# I would have liked to conditionalize this, but
+# that appears to break other things http://bugzilla.gnome.org/show_bug.cgi?id=156399
+GTK_DOC_CHECK([1.0])
+AM_CONDITIONAL(GTK_DOC_INSTALLED, $gtk_doc_installed)
+
+
+### Checks for libraries.
+# gtk >= 2.12 is needed for GtkBuilder
+PKG_CHECK_MODULES(GCE, gtk+-2.0 >= 2.12.0 libcroco-0.6)
+
+AC_SUBST([GCE_CFLAGS])
+AC_SUBST([GCE_LIBS])
+
+AC_DEFINE([CCD_WITH_GTK], [1], [Support for drawing Gtk+ primitives like `box-gap'])
+AM_CONDITIONAL([CCD_WITH_GTK], [test "yes" = "yes"])
+
+AC_SUBST([CCD_CFLAGS], [$GCE_CFLAGS])
+AC_SUBST([CCD_LIBS], [$GCE_LIBS])
+
+### Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([stdbool.h stdint.h stdio.h stdlib.h string.h])
+
+### Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+
+set_more_warnings=yes
+if test "$GCC" = "yes" -a "$CC" != 'g++' -a "x$set_more_warnings" != "xno"; then
+ for option in -std=c99 -pedantic -Wall -Wsign-compare -Wpointer-arith -Wnested-externs -Wchar-subscripts -Wwrite-strings -Wdeclaration-after-statement -Wnested-externs -Wmissing-noreturn -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wno-pointer-sign \
+ -Wbitwise -Wcast-to-as -Wdefault-bitfield-sign -Wdo-while -Wparen-string -Wptr-subtraction-blows -Wreturn-void -Wtypesign ; do
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $option"
+ AC_MSG_CHECKING([whether gcc understands $option])
+ AC_TRY_COMPILE([], [],
+ has_option=yes,
+ has_option=no,)
+ if test $has_option = no; then
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ AC_MSG_RESULT($has_option)
+ unset has_option
+ unset SAVE_CFLAGS
+ done
+ unset option
+fi
+
+AC_CONFIG_FILES([
+ Makefile
+ libccd/Makefile
+ libccd/ccd/Makefile
+ libccd/doc/Makefile
+ libccd/doc/version.xml
+ libccd/examples/Makefile
+ src/Makefile
+ themes/Makefile
+ themes/gtk-css-test/Makefile
+ themes/gtk-css-test/gtk-2.0/Makefile])
+AC_OUTPUT
+
Added: bzr-playground/libccd/Makefile.am
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/Makefile.am Mon Aug 18 13:50:33 2008
@@ -0,0 +1,7 @@
+
+SUBDIRS = ccd doc
+
+if CCD_WITH_GTK
+SUBDIRS += examples
+endif
+
Added: bzr-playground/libccd/ccd/Makefile.am
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/Makefile.am Mon Aug 18 13:50:33 2008
@@ -0,0 +1,48 @@
+
+AM_CPPFLAGS = \
+ $(CCD_CFLAGS) \
+ -I$(top_srcdir)/libccd \
+ -I$(top_builddir)/libccd
+
+noinst_LTLIBRARIES = libccd.la
+
+libccd_la_SOURCES = \
+ ccd-background.c \
+ ccd-background.h \
+ ccd-block.c \
+ ccd-block.h \
+ ccd-border.c \
+ ccd-border.h \
+ ccd-color.c \
+ ccd-color.h \
+ ccd-features.h \
+ ccd.c \
+ ccd.h \
+ ccd-image.c \
+ ccd-image.h \
+ ccd-node.c \
+ ccd-node.h \
+ ccd-parser.c \
+ ccd-parser.h \
+ ccd-property.c \
+ ccd-property.h \
+ ccd-selector-group.c \
+ ccd-selector-group.h \
+ ccd-selector-group-priv.h \
+ ccd-selector.c \
+ ccd-selector.h \
+ ccd-style.c \
+ ccd-style.h \
+ ccd-stylesheet.c \
+ ccd-stylesheet.h \
+ ccd-utils.h
+
+if CCD_WITH_GTK
+libccd_la_SOURCES += \
+ ccd-gtk-style.c \
+ ccd-gtk-style.h
+endif
+
+EXTRA_DIST = \
+ ccd-features.h.in
+
Added: bzr-playground/libccd/ccd/ccd-background.c
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-background.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,96 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include "ccd-background.h"
+
+ccd_background_t *
+ccd_background_new (void)
+{
+ return g_new0 (ccd_background_t, 1);
+}
+
+void
+ccd_background_free (ccd_background_t *self)
+{
+ g_free (self);
+}
+
+bool
+ccd_background_parse (ccd_background_t *self,
+ char const *property,
+ CRTerm const *values)
+{
+ ccd_property_spec_t type;
+
+ type = CCD_PROPERTY_SPEC_UNKNOWN;
+ if (0 == strcmp ("background-color", property)) {
+ type = ccd_color_parse (&self->color, values);
+ g_return_val_if_fail (type != CCD_PROPERTY_SPEC_UNKNOWN, false);
+ self->color_type = type;
+ return true;
+ } else if (0 == strcmp ("background-image", property)) {
+ type = ccd_image_parse (&self->image, values);
+ g_return_val_if_fail (type != CCD_PROPERTY_SPEC_UNKNOWN, false);
+ self->image_type = type;
+ return true;
+ }
+
+ return false;
+}
+
+void
+ccd_background_draw (ccd_background_t const *self,
+ cairo_t *cr,
+ int32_t x,
+ int32_t y,
+ int32_t width,
+ int32_t height)
+{
+ g_assert (self);
+
+ if (self->color_type != CCD_PROPERTY_SPEC_UNKNOWN) {
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_set_source_rgb (cr, self->color.red, self->color.green, self->color.blue);
+ cairo_fill (cr);
+ }
+}
+
+void
+ccd_background_dump (ccd_background_t const *self)
+{
+ printf (" background-color: ");
+ switch (self->color_type) {
+ case CCD_PROPERTY_SPEC_NONE:
+ printf ("none");
+ break;
+ case CCD_PROPERTY_SPEC_INHERIT:
+ printf ("inherit");
+ break;
+ case CCD_PROPERTY_SPEC_SPECIFIC:
+ ccd_color_dump (&self->color);
+ break;
+ case CCD_PROPERTY_SPEC_UNKNOWN:
+ /* fall thru */
+ ;
+ }
+
+ printf (";\n");
+}
+
Added: bzr-playground/libccd/ccd/ccd-background.h
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-background.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,55 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_BACKGROUND_H
+#define CCD_BACKGROUND_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <cairo.h>
+#include <glib.h>
+#include <ccd/ccd-features.h>
+#include <ccd/ccd-color.h>
+#include <ccd/ccd-image.h>
+#include <ccd/ccd-property.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+ ccd_color_t color;
+ ccd_property_spec_t color_type;
+ ccd_image_t image;
+ ccd_property_spec_t image_type;
+} ccd_background_t;
+
+ccd_background_t * ccd_background_new (void);
+void ccd_background_free (ccd_background_t *self);
+
+bool ccd_background_parse (ccd_background_t *self, char const *property,
+ CRTerm const *values);
+
+void ccd_background_draw (ccd_background_t const *self, cairo_t *cr,
+ int32_t x, int32_t y, int32_t width, int32_t height);
+
+void ccd_background_dump (ccd_background_t const *self);
+
+G_END_DECLS
+
+#endif /* CCD_BACKGROUND_H */
+
Added: bzr-playground/libccd/ccd/ccd-block.c
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-block.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,46 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ccd-block.h"
+
+ccd_block_t *
+ccd_block_new (void)
+{
+ ccd_block_t *self;
+
+ self = g_new0 (ccd_block_t, 1);
+
+ return self;
+}
+
+void
+ccd_block_free (ccd_block_t *self)
+{
+ g_assert (self);
+
+ g_free (self);
+}
+
+void
+ccd_block_dump (ccd_block_t const *self)
+{
+ ccd_background_dump (&self->background);
+ ccd_border_dump (&self->border);
+}
+
Added: bzr-playground/libccd/ccd/ccd-block.h
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-block.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,45 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_BLOCK_H
+#define CCD_BLOCK_H
+
+#include <glib.h>
+#include <cairo.h>
+#include <ccd/ccd-features.h>
+#include <ccd/ccd-background.h>
+#include <ccd/ccd-border.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+ /*< private >*/
+ ccd_background_t background;
+ ccd_border_t border;
+} ccd_block_t;
+
+ccd_block_t * ccd_block_new (void);
+void ccd_block_free (ccd_block_t *self);
+
+void ccd_block_dump (ccd_block_t const *self);
+
+G_END_DECLS
+
+#endif /* CCD_BLOCK_H */
+
Added: bzr-playground/libccd/ccd/ccd-border.c
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-border.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,431 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "ccd-border.h"
+#include "ccd-utils.h"
+
+#define SET_COMMON_WIDTH(cond_, border_, val_) \
+if (cond_ && !(CCD_BORDER_FLAGS_SPECIFIC_WIDTH & border_.flags)) { \
+ border_.width = val_; \
+ border_.flags |= CCD_BORDER_FLAGS_COMMON_WIDTH; \
+}
+
+#define SET_SPECIFIC_WIDTH(cond_, border_, val_) \
+if (cond_) { \
+ border_.width = val_; \
+ border_.flags |= CCD_BORDER_FLAGS_SPECIFIC_WIDTH; \
+}
+
+#define SET_COMMON_STYLE(cond_, border_, val_) \
+if (cond_ && !(CCD_BORDER_FLAGS_SPECIFIC_STYLE & border_.flags)) { \
+ border_.style = val_; \
+ border_.flags |= CCD_BORDER_FLAGS_COMMON_STYLE; \
+}
+
+#define SET_SPECIFIC_STYLE(cond_, border_, val_) \
+if (cond_) { \
+ border_.style = val_; \
+ border_.flags |= CCD_BORDER_FLAGS_SPECIFIC_STYLE; \
+}
+
+#define SET_COMMON_COLOR(cond_, border_, val_) \
+if (cond_ && !(CCD_BORDER_FLAGS_SPECIFIC_COLOR & border_.flags)) { \
+ border_.color.red = val_.red; \
+ border_.color.green = val_.green; \
+ border_.color.blue = val_.blue; \
+ border_.flags |= CCD_BORDER_FLAGS_COMMON_COLOR; \
+}
+
+#define SET_SPECIFIC_COLOR(cond_, border_, val_) \
+if (cond_) { \
+ border_.color.red = val_.red; \
+ border_.color.green = val_.green; \
+ border_.color.blue = val_.blue; \
+ border_.flags |= CCD_BORDER_FLAGS_SPECIFIC_COLOR; \
+}
+
+/*!
+ * Map between border style css string and internal value.
+ */
+static const struct {
+ ccd_border_style_t border_style;
+ char const *css;
+} _border_style_map[] = {
+ { CCD_BORDER_STYLE_HIDDEN, "hidden" },
+ { CCD_BORDER_STYLE_DOTTED, "dotted" },
+ { CCD_BORDER_STYLE_DASHED, "dashed" },
+ { CCD_BORDER_STYLE_SOLID, "solid" },
+ { CCD_BORDER_STYLE_DOUBLE, "double" },
+ { CCD_BORDER_STYLE_GROOVE, "groove" },
+ { CCD_BORDER_STYLE_RIDGE, "ridge" },
+ { CCD_BORDER_STYLE_INSET, "inset" },
+ { CCD_BORDER_STYLE_OUTSET, "outset" }
+};
+
+static bool
+match_style (char const *css_border_style,
+ ccd_border_style_t *style)
+{
+ g_return_val_if_fail (css_border_style && *css_border_style, false);
+
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_border_style_map); i++) {
+ if (0 == strcmp (_border_style_map[i].css, css_border_style)) {
+ *style = _border_style_map[i].border_style;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static char const *
+lookup_name (ccd_border_style_t border_style)
+{
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_border_style_map); i++) {
+ if (_border_style_map[i].border_style == border_style) {
+ return _border_style_map[i].css;
+ }
+ }
+
+ return NULL;
+}
+
+ccd_border_t *
+ccd_border_new (void)
+{
+ return g_new0 (ccd_border_t, 1);
+}
+
+void
+ccd_border_free (ccd_border_t *self)
+{
+ g_free (self);
+}
+
+/*
+ * Parse properties of the form
+ * - border: ; # only to prevent errors
+ * - border: 1px;
+ * - border: solid;
+ * - border: 1px solid;
+ * - border: red;
+ * - border: 1px red;
+ * - border: 1px solid red;
+ */
+bool
+ccd_border_parse (ccd_border_t *self,
+ char const *property,
+ CRTerm const *values)
+{
+ CRTerm const *iter;
+ double width;
+ ccd_border_style_t style;
+ ccd_color_t color;
+ ccd_property_spec_t type;
+ bool have_width;
+ bool have_color;
+ bool have_style;
+
+/* TODO set per stroke or for whole border
+ type = ccd_property_parse_type (values);
+ if (CCD_PROPERTY_SPEC_NONE == type ||
+ CCD_PROPERTY_SPEC_INHERIT == type) {
+ self->type = type;
+ return true;
+ }
+*/
+
+ iter = values;
+
+ have_width = false;
+ width = 0; /* prevent warning */
+ if (iter &&
+ TERM_NUMBER == iter->type) {
+ /* width */
+ width = iter->content.num->val;
+ iter = iter->next;
+ have_width = true;
+ }
+
+ have_style = false;
+ style = CCD_BORDER_STYLE_SOLID; /* prevent warning */
+ if (iter &&
+ TERM_IDENT == iter->type &&
+ match_style (cr_string_peek_raw_str (iter->content.str), &style)) {
+ /* style */
+ iter = iter->next;
+ have_style = true;
+ }
+
+ have_color = false;
+ color.red = color.green = color.blue = 0; /* prevent warning */
+ if (iter &&
+ ccd_color_parse (&color, iter)) {
+ /* color */
+ iter = iter->next;
+ have_color = true;
+ }
+
+ if (0 == strcmp ("border", property)) {
+
+ SET_COMMON_WIDTH (have_width, self->left, width);
+ SET_COMMON_WIDTH (have_width, self->top, width);
+ SET_COMMON_WIDTH (have_width, self->right, width);
+ SET_COMMON_WIDTH (have_width, self->bottom, width);
+
+ SET_COMMON_STYLE (have_style, self->left, style);
+ SET_COMMON_STYLE (have_style, self->top, style);
+ SET_COMMON_STYLE (have_style, self->right, style);
+ SET_COMMON_STYLE (have_style, self->bottom, style);
+
+ SET_COMMON_COLOR (have_color, self->left, color);
+ SET_COMMON_COLOR (have_color, self->top, color);
+ SET_COMMON_COLOR (have_color, self->right, color);
+ SET_COMMON_COLOR (have_color, self->bottom, color);
+
+ } else if (0 == strcmp ("border-left", property)) {
+
+ SET_SPECIFIC_WIDTH (have_width, self->left, width);
+ SET_SPECIFIC_STYLE (have_style, self->left, style);
+ SET_SPECIFIC_COLOR (have_color, self->left, color);
+
+ } else if (0 == strcmp ("border-top", property)) {
+
+ SET_SPECIFIC_WIDTH (have_width, self->top, width);
+ SET_SPECIFIC_STYLE (have_style, self->top, style);
+ SET_SPECIFIC_COLOR (have_color, self->top, color);
+
+ } else if (0 == strcmp ("border-right", property)) {
+
+ SET_SPECIFIC_WIDTH (have_width, self->right, width);
+ SET_SPECIFIC_STYLE (have_style, self->right, style);
+ SET_SPECIFIC_COLOR (have_color, self->right, color);
+
+ } else if (0 == strcmp ("border-bottom", property)) {
+
+ SET_SPECIFIC_WIDTH (have_width, self->bottom, width);
+ SET_SPECIFIC_STYLE (have_style, self->bottom, style);
+ SET_SPECIFIC_COLOR (have_color, self->bottom, color);
+
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+static void
+draw_none (ccd_border_stroke_t const *stroke,
+ cairo_t *cr,
+ double x1,
+ double y1,
+ double x2,
+ double y2)
+{}
+
+static void
+draw_dotted (ccd_border_stroke_t const *stroke,
+ cairo_t *cr,
+ double x1,
+ double y1,
+ double x2,
+ double y2)
+{
+ double dash_len;
+
+ dash_len = stroke->width;
+
+ cairo_save (cr);
+
+ cairo_move_to (cr, x1, y1);
+ cairo_line_to (cr, x2, y2);
+ cairo_set_dash (cr, &dash_len, 1, 0);
+ cairo_set_line_width (cr, stroke->width);
+ cairo_set_source_rgb (cr, stroke->color.red, stroke->color.green,
+ stroke->color.blue);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+static void
+draw_dashed (ccd_border_stroke_t const *stroke,
+ cairo_t *cr,
+ double x1,
+ double y1,
+ double x2,
+ double y2)
+{
+ double dashes[2];
+
+ dashes[0] = stroke->width * 3;
+ dashes[1] = stroke->width * 3;
+
+ cairo_save (cr);
+
+ cairo_move_to (cr, x1, y1);
+ cairo_line_to (cr, x2, y2);
+ cairo_set_dash (cr, dashes, G_N_ELEMENTS (dashes), 0);
+ cairo_set_line_width (cr, stroke->width);
+ cairo_set_source_rgb (cr, stroke->color.red, stroke->color.green,
+ stroke->color.blue);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+static void
+draw_solid (ccd_border_stroke_t const *stroke,
+ cairo_t *cr,
+ double x1,
+ double y1,
+ double x2,
+ double y2)
+{
+ cairo_save (cr);
+
+ cairo_move_to (cr, x1, y1);
+ cairo_line_to (cr, x2, y2);
+ cairo_set_line_width (cr, stroke->width);
+ cairo_set_source_rgb (cr, stroke->color.red, stroke->color.green,
+ stroke->color.blue);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+typedef void (*draw_f) (ccd_border_stroke_t const *, cairo_t *,
+ double, double, double, double);
+
+static draw_f
+get_draw_func (ccd_border_stroke_t const *stroke)
+{
+ if (CCD_PROPERTY_SPEC_NONE == stroke->type) {
+ return draw_none;
+ }
+
+ switch (stroke->style) {
+ case CCD_BORDER_STYLE_HIDDEN:
+ g_warning ("CCD_BORDER_STYLE_HIDDEN not implemented");
+ return draw_none;
+ case CCD_BORDER_STYLE_DOTTED:
+ return draw_dotted;
+ case CCD_BORDER_STYLE_DASHED:
+ return draw_dashed;
+ case CCD_BORDER_STYLE_SOLID:
+ return draw_solid;
+ case CCD_BORDER_STYLE_DOUBLE:
+ g_warning ("CCD_BORDER_STYLE_DOUBLE not implemented");
+ case CCD_BORDER_STYLE_GROOVE:
+ g_warning ("CCD_BORDER_STYLE_GROOVE not implemented");
+ case CCD_BORDER_STYLE_RIDGE:
+ g_warning ("CCD_BORDER_STYLE_RIDGE not implemented");
+ case CCD_BORDER_STYLE_INSET:
+ g_warning ("CCD_BORDER_STYLE_INSET not implemented");
+ case CCD_BORDER_STYLE_OUTSET:
+ g_warning ("CCD_BORDER_STYLE_OUTSET not implemented");
+ default:
+ g_assert_not_reached ();
+ return draw_solid;
+ }
+}
+
+void
+ccd_border_draw (ccd_border_stroke_t const *left,
+ ccd_border_stroke_t const *top,
+ ccd_border_stroke_t const *right,
+ ccd_border_stroke_t const *bottom,
+ cairo_t *cr,
+ double x,
+ double y,
+ double width,
+ double height)
+{
+ draw_f draw_func;
+ double off;
+
+ if (left) {
+ draw_func = get_draw_func (left);
+ off = left->width / 2.;
+ draw_func (left, cr, x + off, y, x + off, y + height);
+ }
+
+ if (top) {
+ draw_func = get_draw_func (top);
+ off = top->width / 2.;
+ draw_func (top, cr, x, y + off, x + width, y + off);
+ }
+
+ if (right) {
+ draw_func = get_draw_func (right);
+ off = right->width / 2.;
+ draw_func (right, cr, x + width - off, y, x + width - off, y + height);
+ }
+
+ if (bottom) {
+ draw_func = get_draw_func (bottom);
+ off = bottom->width / 2.;
+ draw_func (bottom, cr, x + width, y + height - off, x, y + height - off);
+ }
+}
+
+void
+ccd_border_dump_stroke (ccd_border_stroke_t const *stroke)
+{
+ if (stroke->flags & CCD_BORDER_FLAGS_WIDTH_MASK) {
+ printf ("%.1f ", stroke->width);
+ }
+
+ if (stroke->flags & CCD_BORDER_FLAGS_STYLE_MASK) {
+ printf ("%s ", lookup_name (stroke->style));
+ }
+
+ if (stroke->flags & CCD_BORDER_FLAGS_COLOR_MASK) {
+ ccd_color_dump (&stroke->color);
+ }
+
+ printf (";\n");
+}
+
+void
+ccd_border_dump (ccd_border_t const *self)
+{
+ if (self->left.flags) {
+ printf (CCD_PROPERTY_DUMP_PREFIX "border-left: ");
+ ccd_border_dump_stroke (&self->left);
+ }
+
+ if (self->top.flags) {
+ printf (CCD_PROPERTY_DUMP_PREFIX "border-top: ");
+ ccd_border_dump_stroke (&self->top);
+ }
+
+ if (self->right.flags) {
+ printf (CCD_PROPERTY_DUMP_PREFIX "border-right: ");
+ ccd_border_dump_stroke (&self->right);
+ }
+
+ if (self->bottom.flags) {
+ printf (CCD_PROPERTY_DUMP_PREFIX "border-bottom: ");
+ ccd_border_dump_stroke (&self->bottom);
+ }
+}
+
Added: bzr-playground/libccd/ccd/ccd-border.h
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-border.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,96 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_BORDER_H
+#define CCD_BORDER_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <cairo.h>
+#include <glib.h>
+#include <ccd/ccd-features.h>
+#include <ccd/ccd-color.h>
+#include <ccd/ccd-property.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+ CCD_BORDER_STYLE_HIDDEN,
+ CCD_BORDER_STYLE_DOTTED,
+ CCD_BORDER_STYLE_DASHED,
+ CCD_BORDER_STYLE_SOLID,
+ CCD_BORDER_STYLE_DOUBLE,
+ CCD_BORDER_STYLE_GROOVE,
+ CCD_BORDER_STYLE_RIDGE,
+ CCD_BORDER_STYLE_INSET,
+ CCD_BORDER_STYLE_OUTSET
+} ccd_border_style_t;
+
+/*
+ * Remember which properties were set explicitely, e.g. using "border-top",
+ * so it's not overwritten by a subsequent "border" property.
+ */
+typedef enum {
+ CCD_BORDER_FLAGS_COMMON_WIDTH = 1 << 0,
+ CCD_BORDER_FLAGS_SPECIFIC_WIDTH = 1 << 1,
+ CCD_BORDER_FLAGS_WIDTH_MASK = CCD_BORDER_FLAGS_COMMON_WIDTH | CCD_BORDER_FLAGS_SPECIFIC_WIDTH,
+
+ CCD_BORDER_FLAGS_COMMON_STYLE = 1 << 2,
+ CCD_BORDER_FLAGS_SPECIFIC_STYLE = 1 << 3,
+ CCD_BORDER_FLAGS_STYLE_MASK = CCD_BORDER_FLAGS_COMMON_STYLE | CCD_BORDER_FLAGS_SPECIFIC_STYLE,
+
+ CCD_BORDER_FLAGS_COMMON_COLOR = 1 << 4,
+ CCD_BORDER_FLAGS_SPECIFIC_COLOR = 1 << 5,
+ CCD_BORDER_FLAGS_COLOR_MASK = CCD_BORDER_FLAGS_COMMON_COLOR | CCD_BORDER_FLAGS_SPECIFIC_COLOR
+} ccd_border_flags_t;
+
+typedef struct {
+ double width;
+ ccd_border_style_t style;
+ ccd_color_t color;
+ ccd_property_spec_t type;
+ int flags;
+} ccd_border_stroke_t;
+
+typedef struct {
+ ccd_border_stroke_t left;
+ ccd_border_stroke_t top;
+ ccd_border_stroke_t right;
+ ccd_border_stroke_t bottom;
+} ccd_border_t;
+
+ccd_border_t * ccd_border_new (void);
+void ccd_border_free (ccd_border_t *self);
+
+bool ccd_border_parse (ccd_border_t *self, char const *property,
+ CRTerm const *values);
+
+void ccd_border_draw (ccd_border_stroke_t const *left,
+ ccd_border_stroke_t const *top,
+ ccd_border_stroke_t const *right,
+ ccd_border_stroke_t const *bottom,
+ cairo_t *cr, double x, double y, double width, double height);
+
+void ccd_border_dump (ccd_border_t const *self);
+void ccd_border_dump_stroke (ccd_border_stroke_t const *stroke);
+
+G_END_DECLS
+
+#endif /* CCD_BORDER_H */
+
Added: bzr-playground/libccd/ccd/ccd-color.c
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-color.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,305 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * Functions ccd_color_parse_hex() and hex() are derived from pango,
+ * Copyright (C) 2000 Red Hat Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include "ccd-color.h"
+
+static const struct {
+ char const *name;
+ const ccd_color_t color;
+} _color_map[] = {
+ { "aliceblue", { 0xf0/255., 0xf8/255., 0xff/255. } },
+ { "antiquewhite", { 0xfa/255., 0xeb/255., 0xd7/255. } },
+ { "aqua", { 0x00/255., 0xff/255., 0xff/255. } },
+ { "aquamarine", { 0x7f/255., 0xff/255., 0xd4/255. } },
+ { "azure", { 0xf0/255., 0xff/255., 0xff/255. } },
+ { "beige", { 0xf5/255., 0xf5/255., 0xdc/255. } },
+ { "bisque", { 0xff/255., 0xe4/255., 0xc4/255. } },
+ { "black", { 0x00/255., 0x00/255., 0x00/255. } },
+ { "blanchedalmond", { 0xff/255., 0xeb/255., 0xcd/255. } },
+ { "blue", { 0x00/255., 0x00/255., 0xff/255. } },
+ { "blueviolet", { 0x8a/255., 0x2b/255., 0xe2/255. } },
+ { "brown", { 0xa5/255., 0x2a/255., 0x2a/255. } },
+ { "burlywood", { 0xde/255., 0xb8/255., 0x87/255. } },
+ { "cadetblue", { 0x5f/255., 0x9e/255., 0xa0/255. } },
+ { "chartreuse", { 0x7f/255., 0xff/255., 0x00/255. } },
+ { "chocolate", { 0xd2/255., 0x69/255., 0x1e/255. } },
+ { "coral", { 0xff/255., 0x7f/255., 0x50/255. } },
+ { "cornflowerblue", { 0x64/255., 0x95/255., 0xed/255. } },
+ { "cornsilk", { 0xff/255., 0xf8/255., 0xdc/255. } },
+ { "crimson", { 0xdc/255., 0x14/255., 0x3c/255. } },
+ { "cyan", { 0x00/255., 0xff/255., 0xff/255. } },
+ { "darkblue", { 0x00/255., 0x00/255., 0x8b/255. } },
+ { "darkcyan", { 0x00/255., 0x8b/255., 0x8b/255. } },
+ { "darkgoldenrod", { 0xb8/255., 0x86/255., 0x0b/255. } },
+ { "darkgray", { 0xa9/255., 0xa9/255., 0xa9/255. } },
+ { "darkgrey", { 0xa9/255., 0xa9/255., 0xa9/255. } },
+ { "darkgreen", { 0x00/255., 0x64/255., 0x00/255. } },
+ { "darkkhaki", { 0xbd/255., 0xb7/255., 0x6b/255. } },
+ { "darkmagenta", { 0x8b/255., 0x00/255., 0x8b/255. } },
+ { "darkolivegreen", { 0x55/255., 0x6b/255., 0x2f/255. } },
+ { "darkorange", { 0xff/255., 0x8c/255., 0x00/255. } },
+ { "darkorchid", { 0x99/255., 0x32/255., 0xcc/255. } },
+ { "darkred", { 0x8b/255., 0x00/255., 0x00/255. } },
+ { "darksalmon", { 0xe9/255., 0x96/255., 0x7a/255. } },
+ { "darkseagreen", { 0x8f/255., 0xbc/255., 0x8f/255. } },
+ { "darkslateblue", { 0x48/255., 0x3d/255., 0x8b/255. } },
+ { "darkslategray", { 0x2f/255., 0x4f/255., 0x4f/255. } },
+ { "darkslategrey", { 0x2f/255., 0x4f/255., 0x4f/255. } },
+ { "darkturquoise", { 0x00/255., 0xce/255., 0xd1/255. } },
+ { "darkviolet", { 0x94/255., 0x00/255., 0xd3/255. } },
+ { "deeppink", { 0xff/255., 0x14/255., 0x93/255. } },
+ { "deepskyblue", { 0x00/255., 0xbf/255., 0xff/255. } },
+ { "dimgray", { 0x69/255., 0x69/255., 0x69/255. } },
+ { "dimgrey", { 0x69/255., 0x69/255., 0x69/255. } },
+ { "dodgerblue", { 0x1e/255., 0x90/255., 0xff/255. } },
+ { "firebrick", { 0xb2/255., 0x22/255., 0x22/255. } },
+ { "floralwhite", { 0xff/255., 0xfa/255., 0xf0/255. } },
+ { "forestgreen", { 0x22/255., 0x8b/255., 0x22/255. } },
+ { "fuchsia", { 0xff/255., 0x00/255., 0xff/255. } },
+ { "gainsboro", { 0xdc/255., 0xdc/255., 0xdc/255. } },
+ { "ghostwhite", { 0xf8/255., 0xf8/255., 0xff/255. } },
+ { "gold", { 0xff/255., 0xd7/255., 0x00/255. } },
+ { "goldenrod", { 0xda/255., 0xa5/255., 0x20/255. } },
+ { "gray", { 0x80/255., 0x80/255., 0x80/255. } },
+ { "grey", { 0x80/255., 0x80/255., 0x80/255. } },
+ { "green", { 0x00/255., 0x80/255., 0x00/255. } },
+ { "greenyellow", { 0xad/255., 0xff/255., 0x2f/255. } },
+ { "honeydew", { 0xf0/255., 0xff/255., 0xf0/255. } },
+ { "hotpink", { 0xff/255., 0x69/255., 0xb4/255. } },
+ { "indianred", { 0xcd/255., 0x5c/255., 0x5c/255. } },
+ { "indigo", { 0x4b/255., 0x00/255., 0x82/255. } },
+ { "ivory", { 0xff/255., 0xff/255., 0xf0/255. } },
+ { "khaki", { 0xf0/255., 0xe6/255., 0x8c/255. } },
+ { "lavender", { 0xe6/255., 0xe6/255., 0xfa/255. } },
+ { "lavenderblush", { 0xff/255., 0xf0/255., 0xf5/255. } },
+ { "lawngreen", { 0x7c/255., 0xfc/255., 0x00/255. } },
+ { "lemonchiffon", { 0xff/255., 0xfa/255., 0xcd/255. } },
+ { "lightblue", { 0xad/255., 0xd8/255., 0xe6/255. } },
+ { "lightcoral", { 0xf0/255., 0x80/255., 0x80/255. } },
+ { "lightcyan", { 0xe0/255., 0xff/255., 0xff/255. } },
+ { "lightgoldenrodyellow", { 0xfa/255., 0xfa/255., 0xd2/255. } },
+ { "lightgray", { 0xd3/255., 0xd3/255., 0xd3/255. } },
+ { "lightgrey", { 0xd3/255., 0xd3/255., 0xd3/255. } },
+ { "lightgreen", { 0x90/255., 0xee/255., 0x90/255. } },
+ { "lightpink", { 0xff/255., 0xb6/255., 0xc1/255. } },
+ { "lightsalmon", { 0xff/255., 0xa0/255., 0x7a/255. } },
+ { "lightseagreen", { 0x20/255., 0xb2/255., 0xaa/255. } },
+ { "lightskyblue", { 0x87/255., 0xce/255., 0xfa/255. } },
+ { "lightslategray", { 0x77/255., 0x88/255., 0x99/255. } },
+ { "lightslategrey", { 0x77/255., 0x88/255., 0x99/255. } },
+ { "lightsteelblue", { 0xb0/255., 0xc4/255., 0xde/255. } },
+ { "lightyellow", { 0xff/255., 0xff/255., 0xe0/255. } },
+ { "lime", { 0x00/255., 0xff/255., 0x00/255. } },
+ { "limegreen", { 0x32/255., 0xcd/255., 0x32/255. } },
+ { "linen", { 0xfa/255., 0xf0/255., 0xe6/255. } },
+ { "magenta", { 0xff/255., 0x00/255., 0xff/255. } },
+ { "maroon", { 0x80/255., 0x00/255., 0x00/255. } },
+ { "mediumaquamarine", { 0x66/255., 0xcd/255., 0xaa/255. } },
+ { "mediumblue", { 0x00/255., 0x00/255., 0xcd/255. } },
+ { "mediumorchid", { 0xba/255., 0x55/255., 0xd3/255. } },
+ { "mediumpurple", { 0x93/255., 0x70/255., 0xd8/255. } },
+ { "mediumseagreen", { 0x3c/255., 0xb3/255., 0x71/255. } },
+ { "mediumslateblue", { 0x7b/255., 0x68/255., 0xee/255. } },
+ { "mediumspringgreen", { 0x00/255., 0xfa/255., 0x9a/255. } },
+ { "mediumturquoise", { 0x48/255., 0xd1/255., 0xcc/255. } },
+ { "mediumvioletred", { 0xc7/255., 0x15/255., 0x85/255. } },
+ { "midnightblue", { 0x19/255., 0x19/255., 0x70/255. } },
+ { "mintcream", { 0xf5/255., 0xff/255., 0xfa/255. } },
+ { "mistyrose", { 0xff/255., 0xe4/255., 0xe1/255. } },
+ { "moccasin", { 0xff/255., 0xe4/255., 0xb5/255. } },
+ { "navajowhite", { 0xff/255., 0xde/255., 0xad/255. } },
+ { "navy", { 0x00/255., 0x00/255., 0x80/255. } },
+ { "oldlace", { 0xfd/255., 0xf5/255., 0xe6/255. } },
+ { "olive", { 0x80/255., 0x80/255., 0x00/255. } },
+ { "olivedrab", { 0x6b/255., 0x8e/255., 0x23/255. } },
+ { "orange", { 0xff/255., 0xa5/255., 0x00/255. } },
+ { "orangered", { 0xff/255., 0x45/255., 0x00/255. } },
+ { "orchid", { 0xda/255., 0x70/255., 0xd6/255. } },
+ { "palegoldenrod", { 0xee/255., 0xe8/255., 0xaa/255. } },
+ { "palegreen", { 0x98/255., 0xfb/255., 0x98/255. } },
+ { "paleturquoise", { 0xaf/255., 0xee/255., 0xee/255. } },
+ { "palevioletred", { 0xd8/255., 0x70/255., 0x93/255. } },
+ { "papayawhip", { 0xff/255., 0xef/255., 0xd5/255. } },
+ { "peachpuff", { 0xff/255., 0xda/255., 0xb9/255. } },
+ { "peru", { 0xcd/255., 0x85/255., 0x3f/255. } },
+ { "pink", { 0xff/255., 0xc0/255., 0xcb/255. } },
+ { "plum", { 0xdd/255., 0xa0/255., 0xdd/255. } },
+ { "powderblue", { 0xb0/255., 0xe0/255., 0xe6/255. } },
+ { "purple", { 0x80/255., 0x00/255., 0x80/255. } },
+ { "red", { 0xff/255., 0x00/255., 0x00/255. } },
+ { "rosybrown", { 0xbc/255., 0x8f/255., 0x8f/255. } },
+ { "royalblue", { 0x41/255., 0x69/255., 0xe1/255. } },
+ { "saddlebrown", { 0x8b/255., 0x45/255., 0x13/255. } },
+ { "salmon", { 0xfa/255., 0x80/255., 0x72/255. } },
+ { "sandybrown", { 0xf4/255., 0xa4/255., 0x60/255. } },
+ { "seagreen", { 0x2e/255., 0x8b/255., 0x57/255. } },
+ { "seashell", { 0xff/255., 0xf5/255., 0xee/255. } },
+ { "sienna", { 0xa0/255., 0x52/255., 0x2d/255. } },
+ { "silver", { 0xc0/255., 0xc0/255., 0xc0/255. } },
+ { "skyblue", { 0x87/255., 0xce/255., 0xeb/255. } },
+ { "slateblue", { 0x6a/255., 0x5a/255., 0xcd/255. } },
+ { "slategray", { 0x70/255., 0x80/255., 0x90/255. } },
+ { "slategrey", { 0x70/255., 0x80/255., 0x90/255. } },
+ { "snow", { 0xff/255., 0xfa/255., 0xfa/255. } },
+ { "springgreen", { 0x00/255., 0xff/255., 0x7f/255. } },
+ { "steelblue", { 0x46/255., 0x82/255., 0xb4/255. } },
+ { "tan", { 0xd2/255., 0xb4/255., 0x8c/255. } },
+ { "teal", { 0x00/255., 0x80/255., 0x80/255. } },
+ { "thistle", { 0xd8/255., 0xbf/255., 0xd8/255. } },
+ { "tomato", { 0xff/255., 0x63/255., 0x47/255. } },
+ { "turquoise", { 0x40/255., 0xe0/255., 0xd0/255. } },
+ { "violet", { 0xee/255., 0x82/255., 0xee/255. } },
+ { "wheat", { 0xf5/255., 0xde/255., 0xb3/255. } },
+ { "white", { 0xff/255., 0xff/255., 0xff/255. } },
+ { "whitesmoke", { 0xf5/255., 0xf5/255., 0xf5/255. } },
+ { "yellow", { 0xff/255., 0xff/255., 0x00/255. } },
+ { "yellowgreen", { 0x9a/255., 0xcd/255., 0x32/255. } },
+};
+
+bool
+ccd_color_parse_name (char const *css_color_name,
+ ccd_color_t *color)
+{
+ g_return_val_if_fail (css_color_name && color, false);
+
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_color_map); i++) {
+ if (0 == g_ascii_strcasecmp (_color_map[i].name, css_color_name)) {
+ color->red = _color_map[i].color.red;
+ color->green = _color_map[i].color.green;
+ color->blue = _color_map[i].color.blue;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static gboolean
+hex (char const *spec,
+ int len,
+ unsigned int *c)
+{
+ const char *end;
+
+ *c = 0;
+ for (end = spec + len; spec != end; spec++)
+ if (g_ascii_isxdigit (*spec))
+ *c = (*c << 4) | g_ascii_xdigit_value (*spec);
+ else
+ return false;
+
+ return true;
+}
+
+bool
+ccd_color_parse_hex (char const *spec,
+ ccd_color_t *color)
+{
+ size_t len;
+ unsigned int r, g, b;
+
+ g_return_val_if_fail (spec, false);
+
+ len = strlen (spec);
+ if (len % 3 || len < 3 || len > 12)
+ return false;
+
+ len /= 3;
+
+ if (!hex (spec, len, &r) ||
+ !hex (spec + len, len, &g) ||
+ !hex (spec + len * 2, len, &b))
+ return false;
+
+ if (color) {
+ int bits = len * 4;
+ r <<= 16 - bits;
+ g <<= 16 - bits;
+ b <<= 16 - bits;
+ while (bits < 16) {
+ r |= (r >> bits);
+ g |= (g >> bits);
+ b |= (b >> bits);
+ bits *= 2;
+ }
+ color->red = r / 255.;
+ color->green = g / 255.;
+ color->blue = b / 255.;
+ }
+
+ return true;
+}
+
+ccd_property_spec_t
+ccd_color_parse (ccd_color_t *self,
+ CRTerm const *value)
+{
+ ccd_property_spec_t type;
+ bool ret;
+
+ g_return_val_if_fail (self && value, false);
+
+ switch (value->type) {
+ case TERM_IDENT:
+ type = ccd_property_parse_type (value);
+ if (type != CCD_PROPERTY_SPEC_UNKNOWN) {
+ return type;
+ }
+ ret = ccd_color_parse_name (
+ cr_string_peek_raw_str (value->content.str), self);
+ if (ret)
+ return CCD_PROPERTY_SPEC_SPECIFIC;
+ else
+ return CCD_PROPERTY_SPEC_UNKNOWN;
+ case TERM_HASH:
+ ret = ccd_color_parse_hex (
+ cr_string_peek_raw_str (value->content.str), self);
+ if (ret)
+ return CCD_PROPERTY_SPEC_SPECIFIC;
+ else
+ return CCD_PROPERTY_SPEC_UNKNOWN;
+ case TERM_RGB:
+ self->red = value->content.rgb->red;
+ self->green = value->content.rgb->green;
+ self->blue = value->content.rgb->blue;
+ return CCD_PROPERTY_SPEC_SPECIFIC;
+ /* fall thru for all other enum values to prevent compiler warnings */
+ case TERM_NO_TYPE:
+ case TERM_NUMBER:
+ case TERM_FUNCTION:
+ case TERM_STRING:
+ case TERM_URI:
+ case TERM_UNICODERANGE:
+ default:
+ return CCD_PROPERTY_SPEC_UNKNOWN;
+ }
+}
+
+void
+ccd_color_dump (ccd_color_t const *self)
+{
+ printf ("rgb(%.3f,%.3f,%.3f)", self->red, self->green, self->blue);
+}
+
Added: bzr-playground/libccd/ccd/ccd-color.h
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-color.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,48 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_COLOR_H
+#define CCD_COLOR_H
+
+#include <stdbool.h>
+#include <glib.h>
+#include <libcroco/libcroco.h>
+#include <ccd/ccd-features.h>
+#include <ccd/ccd-property.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+ double red;
+ double green;
+ double blue;
+} ccd_color_t;
+
+bool ccd_color_parse_name (char const *css_color_name, ccd_color_t *color);
+
+bool ccd_color_parse_hex (char const *OxRRGGBB, ccd_color_t *color);
+
+ccd_property_spec_t ccd_color_parse (ccd_color_t *self, CRTerm const *value);
+
+void ccd_color_dump (ccd_color_t const *self);
+
+G_END_DECLS
+
+#endif /* CCD_COLOR_H */
+
Added: bzr-playground/libccd/ccd/ccd-features.h.in
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-features.h.in Mon Aug 18 13:50:33 2008
@@ -0,0 +1,30 @@
+/* The CSS Box Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_FEATURES_H
+#define CCD_FEATURES_H
+
+/* Enable debug code */
+#undef CCD_DEBUG
+
+/* Support for drawing Gtk+ primitives like `box-gap' */
+#undef CCD_WITH_GTK
+
+#endif /* CCD_FEATURES_H */
+
Added: bzr-playground/libccd/ccd/ccd-gtk-style.c
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-gtk-style.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,125 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ccd-gtk-style.h"
+
+/**
+ * ccd_style_draw_gap:
+ * @self: a ccd_style_t.
+ * @cr: the target to draw onto.
+ * @x: the starting x coordinate.
+ * @y: the starting y coordinate.
+ * @width: width of the outline to draw.
+ * @height: height of the outline to draw.
+ * @gap_side: side in which to leave the gap.
+ * @gap_start: starting position of the gap.
+ * @gap_width: width of the gap.
+ *
+ * Draw a rectangle with gap using this style instance.
+ **/
+void
+ccd_style_draw_gap (ccd_style_t const *self,
+ cairo_t *cr,
+ int32_t x,
+ int32_t y,
+ int32_t width,
+ int32_t height,
+ GtkPositionType gap_side,
+ int32_t gap_start,
+ int32_t gap_width)
+{
+ if (self->background) {
+ ccd_background_draw (self->background, cr, x, y, width, height);
+ }
+
+ switch (gap_side) {
+ case GTK_POS_LEFT:
+ if (gap_start > y || gap_width < height) {
+ /* Draw gap only if it's not over the whole border. */
+ ccd_border_draw (self->left, NULL, NULL, NULL, cr,
+ x, y, 0, gap_start);
+ ccd_border_draw (self->left, NULL, NULL, NULL, cr,
+ x, y + gap_start + gap_width,
+ 0, height - gap_start - gap_width);
+ }
+ ccd_border_draw (NULL, self->top, self->right, self->bottom, cr,
+ x, y, width, height);
+ break;
+ case GTK_POS_TOP:
+ if (gap_start > x || gap_width < width) {
+ /* Draw gap only if it's not over the whole border. */
+ ccd_border_draw (NULL, self->top, NULL, NULL, cr,
+ x, y, gap_start, 0);
+ ccd_border_draw (NULL, self->top, NULL, NULL, cr,
+ x + gap_start + gap_width, y,
+ width - gap_start - gap_width, 0);
+ }
+ ccd_border_draw (self->left, NULL, self->right, self->bottom, cr,
+ x, y, width, height);
+ break;
+ case GTK_POS_RIGHT:
+ if (gap_start > y || gap_width < height) {
+ /* Draw gap only if it's not over the whole border. */
+ ccd_border_draw (self->left, NULL, NULL, NULL, cr,
+ x + width, y, 0, gap_start);
+ ccd_border_draw (self->left, NULL, NULL, NULL, cr,
+ x + width, y + gap_start + gap_width,
+ 0, height - gap_start - gap_width);
+ }
+ ccd_border_draw (self->left, self->top, NULL, self->bottom, cr,
+ x, y, width, height);
+ break;
+ case GTK_POS_BOTTOM:
+ if (gap_start > x || gap_width < width) {
+ /* Draw gap only if it's not over the whole border. */
+ ccd_border_draw (NULL, NULL, NULL, self->bottom, cr,
+ x, y + height, gap_start, 0);
+ ccd_border_draw (NULL, NULL, NULL, self->bottom, cr,
+ x + gap_start + gap_width, y + height,
+ width - gap_start - gap_width, 0);
+ }
+ ccd_border_draw (self->left, self->top, self->right, NULL, cr,
+ x, y, width, height);
+ break;
+ default:
+ g_assert_not_reached ();
+ return; /* prevent error building without assertions */
+ }
+}
+
+/**
+ * ccd_style_draw_polygon:
+ * @self: a ccd_style_t.
+ * @cr: the target to draw onto.
+ * @points: an array of #GdkPoint<!-- -->s.
+ * @n_points: length of @points.
+ * @fill: %true if the polygon should be filled.
+ *
+ * Draw a rectangle with gap using this style instance.
+ **/
+void
+ccd_style_draw_polygon (ccd_style_t const *self,
+ cairo_t *cr,
+ GdkPoint *points,
+ int32_t n_points,
+ bool fill)
+{
+
+}
+
Added: bzr-playground/libccd/ccd/ccd-gtk-style.h
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-gtk-style.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,43 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_GTK_STYLE_H
+#define CCD_GTK_STYLE_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <cairo.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <ccd/ccd-features.h>
+#include <ccd/ccd-style.h>
+
+G_BEGIN_DECLS
+
+void ccd_style_draw_gap (ccd_style_t const *self, cairo_t *cr,
+ int32_t x, int32_t y, int32_t width, int32_t height,
+ GtkPositionType gap_side, int32_t gap_x, int32_t gap_width);
+
+void ccd_style_draw_polygon (ccd_style_t const *self, cairo_t *cr,
+ GdkPoint *points, int32_t n_points, bool fill);
+
+G_END_DECLS
+
+#endif /* CCD_GTK_STYLE_H */
+
Added: bzr-playground/libccd/ccd/ccd-image.c
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-image.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,89 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * Functions ccd_color_parse_hex() and hex() are derived from pango,
+ * Copyright (C) 2000 Red Hat Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdbool.h>
+#include <string.h>
+#include "ccd-image.h"
+
+void
+ccd_image_discard (ccd_image_t *self)
+{
+ if (self->uri) {
+ g_free (self->uri);
+ self->uri = NULL;
+ }
+
+ if (self->surface) {
+ cairo_surface_destroy (self->surface);
+ self->surface = NULL;
+ }
+}
+
+static bool
+load_image (ccd_image_t *self,
+ char const *uri)
+{
+ // TODO continue here.
+// cairo_surface_t* cairo_image_surface_create_from_png (const char *filename);
+
+ return true;
+}
+
+ccd_property_spec_t
+ccd_image_parse (ccd_image_t *self,
+ CRTerm const *value)
+{
+ bool ret;
+
+ switch (value->type) {
+ case TERM_IDENT:
+ if (0 == strcmp ("none",
+ cr_string_peek_raw_str (value->content.str))) {
+ self->uri = g_strdup ("none");
+ return CCD_PROPERTY_SPEC_NONE;
+ } else if (0 == strcmp ("inherit",
+ cr_string_peek_raw_str (value->content.str))) {
+ self->uri = g_strdup ("inherit");
+ return CCD_PROPERTY_SPEC_INHERIT;
+ } else {
+ return CCD_PROPERTY_SPEC_UNKNOWN;
+ }
+ break;
+ case TERM_URI:
+ self->uri = g_strdup (cr_string_peek_raw_str (value->content.str));
+ ret = load_image (self, self->uri);
+ if (ret)
+ return CCD_PROPERTY_SPEC_SPECIFIC;
+ else
+ return CCD_PROPERTY_SPEC_UNKNOWN;
+ break;
+ default:
+ return CCD_PROPERTY_SPEC_UNKNOWN;
+ }
+}
+
+void
+ccd_image_dump (ccd_image_t const *self)
+{
+ printf ("%s", self->uri);
+}
+
Added: bzr-playground/libccd/ccd/ccd-image.h
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-image.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,45 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_IMAGE_H
+#define CCD_IMAGE_H
+
+#include <cairo.h>
+#include <glib.h>
+#include <libcroco/libcroco.h>
+#include <ccd/ccd-features.h>
+#include <ccd/ccd-property.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+ char *uri;
+ cairo_surface_t *surface;
+} ccd_image_t;
+
+ccd_property_spec_t ccd_image_parse (ccd_image_t *self, CRTerm const *value);
+
+void ccd_image_discard (ccd_image_t *self);
+
+void ccd_image_dump (ccd_image_t const *self);
+
+G_END_DECLS
+
+#endif /* CCD_IMAGE_H */
+
Added: bzr-playground/libccd/ccd/ccd-node.c
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-node.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,134 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ccd-node.h"
+
+static bool
+is_a (ccd_node_t const *self,
+ char const *type_name)
+{
+ return FALSE;
+}
+
+static ccd_node_t *
+get_container (ccd_node_t const *self)
+{
+ return NULL;
+}
+
+static ccd_node_t *
+get_base_style (ccd_node_t const *self)
+{
+ return NULL;
+}
+
+static char const *
+get_type (ccd_node_t const *self)
+{
+ return NULL;
+}
+
+static char const *
+get_id (ccd_node_t const *self)
+{
+ return NULL;
+}
+
+static char const *
+get_class (ccd_node_t const *self)
+{
+ return NULL;
+}
+
+static char const *
+get_pseudo_class (ccd_node_t const *self)
+{
+ return NULL;
+}
+
+static char const *
+get_attribute (ccd_node_t const *self,
+ char const *name)
+{
+ return NULL;
+}
+
+static void
+release (ccd_node_t *self)
+{
+ return;
+}
+
+static const ccd_node_class_t _default_node_class = {
+ .is_a = is_a,
+ .get_container = get_container,
+ .get_base_style = get_base_style,
+ .get_id = get_id,
+ .get_type = get_type,
+ .get_class = get_class,
+ .get_pseudo_class = get_pseudo_class,
+ .get_attribute = get_attribute,
+ .release = release
+};
+
+static ccd_node_class_t _node_class = {
+ .is_a = is_a,
+ .get_container = get_container,
+ .get_base_style = get_base_style,
+ .get_id = get_id,
+ .get_type = get_type,
+ .get_class = get_class,
+ .get_pseudo_class = get_pseudo_class,
+ .get_attribute = get_attribute,
+ .release = release
+};
+
+ccd_node_class_t const *
+ccd_node_get_class (void)
+{
+ return &_node_class;
+}
+
+typedef void (*node_f) (void);
+#define N_ELEMENTS(vtable_) (sizeof (vtable_) / sizeof (node_f))
+
+void
+ccd_node_set_class (ccd_node_class_t const *node_class)
+{
+ node_f *node_vtable;
+ node_f const *new_node_vtable;
+
+ g_return_if_fail (node_class);
+
+ node_vtable = (node_f *) &_node_class;
+ new_node_vtable = (node_f *) node_class;
+ for (unsigned int i = 0; i < N_ELEMENTS (_node_class); i++) {
+ /* Override only implemented methods. */
+ if (new_node_vtable[i]) {
+ node_vtable[i] = new_node_vtable[i];
+ }
+ }
+}
+
+void
+ccd_node_reset_class (void)
+{
+ ccd_node_set_class (&_default_node_class);
+}
+
Added: bzr-playground/libccd/ccd/ccd-node.h
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-node.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,172 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_NODE_H
+#define CCD_NODE_H
+
+#include <stdbool.h>
+#include <glib.h>
+#include <ccd/ccd-features.h>
+
+G_BEGIN_DECLS
+
+/**
+ * ccd_node_t:
+ *
+ * Stack-allocatable struct representing a document node. Used for querying the
+ * #ccd_stylesheet_t.
+ *
+ * <emphasis>Memory management:</emphasis> Unless specified otherwise, objects
+ * of this kind are under the responsibility of the libccd consumer.
+ **/
+typedef void * ccd_node_t;
+
+/**
+ * ccd_node_is_a_f:
+ * @self: a #ccd_node_t.
+ *
+ * Hook function to query whether a #ccd_node_t is of a certain type.
+ *
+ * Returns: %TRUE if matches.
+ **/
+typedef bool (*ccd_node_is_a_f) (ccd_node_t const *self,
+ char const *type_name);
+
+/**
+ * ccd_node_get_container_f:
+ * @self: a #ccd_node_t.
+ *
+ * Hook function to query the container of a #ccd_node_t.
+ *
+ * Returns: newly allocated container node or %NULL.
+ **/
+typedef ccd_node_t * (*ccd_node_get_container_f) (ccd_node_t const *self);
+
+/**
+ * ccd_node_get_base_style_f:
+ * @self: a #ccd_node_t.
+ *
+ * Hook function to query the name of the style a #ccd_node_t derives from.
+ *
+ * Returns: base style or %NULL. The returned value must be valid until
+ * it is released.
+ **/
+typedef ccd_node_t * (*ccd_node_get_base_style_f) (ccd_node_t const *self);
+
+/**
+ * ccd_node_get_type_f:
+ * @self: a #ccd_node_t.
+ *
+ * Hook function to query the type name of a #ccd_node_t.
+ *
+ * Returns: node type name or %NULL. The returned value must be valid until
+ * the current stylesheet query returns.
+ **/
+typedef const char * (*ccd_node_get_type_f) (ccd_node_t const *self);
+
+/**
+ * ccd_node_get_id_f:
+ * @self: a #ccd_node_t.
+ *
+ * Hook function to query the ID of a #ccd_node_t.
+ *
+ * Returns: node ID or %NULL. The returned value must be valid until
+ * the current stylesheet query returns.
+ **/
+typedef const char * (*ccd_node_get_id_f) (ccd_node_t const *self);
+
+/**
+ * ccd_node_get_class_f:
+ * @self: a #ccd_node_t.
+ *
+ * Hook function to query the class name of a #ccd_node_t.
+ *
+ * Returns: node class name or %NULL. The returned value must be valid until
+ * the current stylesheet query returns.
+ **/
+typedef const char * (*ccd_node_get_class_f) (ccd_node_t const *self);
+
+/**
+ * ccd_node_get_pseudo_class_f:
+ * @self: a #ccd_node_t.
+ *
+ * Hook function to query the pseudo-class name of a #ccd_node_t.
+ *
+ * Returns: node pseudo-class name or %NULL. The returned value must be valid until
+ * the current stylesheet query returns.
+ **/
+typedef const char * (*ccd_node_get_pseudo_class_f) (ccd_node_t const *self);
+
+/**
+ * ccd_node_get_attribute_f:
+ * @self: a #ccd_node_t.
+ * @name: attribute name.
+ *
+ * Hook function to query a #ccd_node_t's attributes.
+ *
+ * Returns: attribute value or %NULL. The returned value must be valid until
+ * the current stylesheet query returns.
+ **/
+typedef const char * (*ccd_node_get_attribute_f) (ccd_node_t const *self,
+ char const *name);
+
+/**
+ * ccd_node_release_f:
+ * @self: a #ccd_node_t.
+ *
+ * Hook function to deallocate a #ccd_node_t instance.
+ **/
+typedef void (*ccd_node_release_f) (ccd_node_t *self);
+
+/**
+ * ccd_node_class_t:
+ * @get_container: a #ccd_node_get_container_f.
+ * @get_base_style: a #ccd_node_get_base_style_f.
+ * @get_id: a #ccd_node_get_id_f.
+ * @get_type: a #ccd_node_get_type_f.
+ * @get_class: a #ccd_node_get_class_f.
+ * @get_pseudo_class: a #ccd_node_get_pseudo_class_f.
+ * @get_attribute: a #ccd_node_get_attribute_f.
+ * @release: a #ccd_node_release_f.
+ *
+ * Dispatch table a CCD consumer has to fill so the selection engine can
+ * retrieve information about the document the document.
+ *
+ * The implemented dispatch table needs to be passed to #ccd_init.
+ **/
+typedef struct {
+ ccd_node_is_a_f is_a;
+ ccd_node_get_container_f get_container;
+ ccd_node_get_base_style_f get_base_style;
+ ccd_node_get_id_f get_id;
+ ccd_node_get_type_f get_type;
+ ccd_node_get_class_f get_class;
+ ccd_node_get_pseudo_class_f get_pseudo_class;
+ ccd_node_get_attribute_f get_attribute;
+ ccd_node_release_f release;
+} ccd_node_class_t;
+
+ccd_node_class_t const * ccd_node_get_class (void);
+void ccd_node_set_class (ccd_node_class_t const *node_class);
+void ccd_node_reset_class (void);
+
+G_END_DECLS
+
+#endif /* CCD_NODE_H */
+
Added: bzr-playground/libccd/ccd/ccd-parser.c
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-parser.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,291 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <libcroco/libcroco.h>
+#include "ccd-block.h"
+#include "ccd-parser.h"
+#include "ccd-selector.h"
+#include "ccd-selector-group-priv.h"
+
+typedef struct {
+ GSList *blocks;
+ GHashTable *type_rules;
+ GHashTable *class_rules;
+ GHashTable *id_rules;
+ ccd_block_t *block;
+} ccd_parser_info_t;
+
+#define HANDLER_GET_INFO(handler_) ((ccd_parser_info_t *) handler->app_data)
+
+static ccd_attribute_selector_match_t
+map_attribute_selector_match (enum AttrMatchWay cr_match)
+{
+ switch (cr_match) {
+ case SET:
+ return CCD_ATTRIBUTE_SELECTOR_MATCH_EXISTS;
+ case EQUALS:
+ return CCD_ATTRIBUTE_SELECTOR_MATCH_EQUALS;
+ case INCLUDES:
+ case DASHMATCH:
+ case NO_MATCH:
+ default:
+ g_assert_not_reached ();
+ }
+
+ /* fall back to (my interpretation of) default behaviour */
+ return CCD_ATTRIBUTE_SELECTOR_MATCH_EXISTS;
+}
+
+static ccd_selector_t *
+walk_additional_selector (CRAdditionalSel *cr_add_sel)
+{
+ ccd_selector_t *selector;
+ char const *name;
+ char const *value;
+ ccd_attribute_selector_match_t match;
+
+ g_return_val_if_fail (cr_add_sel, NULL);
+
+ name = NULL;
+ value = NULL;
+ selector = NULL;
+ switch (cr_add_sel->type) {
+ case CLASS_ADD_SELECTOR:
+ name = cr_string_peek_raw_str (cr_add_sel->content.class_name);
+ selector = ccd_class_selector_new (name);
+ break;
+ case PSEUDO_CLASS_ADD_SELECTOR:
+ name = cr_string_peek_raw_str (cr_add_sel->content.pseudo->name);
+ selector = ccd_pseudo_class_selector_new (name);
+ break;
+ case ID_ADD_SELECTOR:
+ name = cr_string_peek_raw_str (cr_add_sel->content.id_name);
+ selector = ccd_pseudo_class_selector_new (name);
+ break;
+ case ATTRIBUTE_ADD_SELECTOR:
+ name = cr_string_peek_raw_str (cr_add_sel->content.attr_sel->name);
+ value = cr_string_peek_raw_str (cr_add_sel->content.attr_sel->value);
+ match = map_attribute_selector_match (cr_add_sel->content.attr_sel->match_way);
+ selector = ccd_attribute_selector_new (name, value, match);
+ break;
+ case NO_ADD_SELECTOR:
+ default:
+ g_assert_not_reached ();
+ }
+
+ g_return_val_if_fail (selector, NULL);
+
+ return selector;
+}
+
+static ccd_selector_t *
+walk_simple_selector_r (CRSimpleSel *cr_simple_sel)
+{
+ ccd_selector_t *selector;
+
+ g_return_val_if_fail (cr_simple_sel, NULL);
+
+ selector = NULL;
+ if (UNIVERSAL_SELECTOR & cr_simple_sel->type_mask) {
+ selector = ccd_universal_selector_new ();
+ } else if (TYPE_SELECTOR & cr_simple_sel->type_mask) {
+ selector = ccd_type_selector_new (cr_string_peek_raw_str (cr_simple_sel->name));
+ } else {
+ char const *sel;
+ sel = cr_simple_sel->name ? cr_string_peek_raw_str (cr_simple_sel->name) : NULL;
+ g_warning ("Unknown selector '%s'\n", sel);
+ return NULL;
+ }
+
+ g_return_val_if_fail (selector, NULL);
+
+ if (cr_simple_sel->add_sel) {
+ ccd_selector_t *refinement;
+ refinement = walk_additional_selector (cr_simple_sel->add_sel);
+ ccd_selector_refine (selector, refinement);
+ }
+
+ if (cr_simple_sel->next) {
+ ccd_selector_t *descendant;
+ descendant = walk_simple_selector_r (cr_simple_sel->next);
+ selector = ccd_selector_append (selector, descendant);
+ }
+
+ return selector;
+}
+
+static void
+start_selector_cb (CRDocHandler *handler,
+ CRSelector *cr_sel)
+{
+ ccd_parser_info_t *info;
+
+ info = HANDLER_GET_INFO (handler);
+
+ g_assert (info && info->block == NULL);
+
+ info->block = ccd_block_new ();
+}
+
+static void
+property_cb (CRDocHandler *handler,
+ CRString *name,
+ CRTerm *values,
+ gboolean is_important)
+{
+ ccd_parser_info_t *info;
+ char const *property;
+
+ info = HANDLER_GET_INFO (handler);
+
+ g_assert (info && info->block);
+
+ property = cr_string_peek_raw_str (name);
+ if (0 == strcmp ("border", property) ||
+ 0 == strncmp ("border-", property, sizeof ("border-") - 1)) {
+ ccd_border_parse (&info->block->border, property, values);
+ } else if (0 == strcmp ("background", property) ||
+ 0 == strncmp ("background-", property, sizeof ("background-") - 1)) {
+ ccd_background_parse (&info->block->background, property, values);
+ }
+}
+
+static void
+end_selector_cb (CRDocHandler *handler,
+ CRSelector *cr_sel)
+{
+ ccd_parser_info_t *info;
+ ccd_selector_t *selector;
+ ccd_selector_group_t *group;
+ CRSelector *iter;
+ GHashTable *rules;
+ char const *key;
+
+ g_assert (HANDLER_GET_INFO (handler));
+
+ info = HANDLER_GET_INFO (handler);
+
+ iter = cr_sel;
+ do {
+ selector = walk_simple_selector_r (iter->simple_sel);
+ if (selector) {
+ ccd_selector_set_block (selector, info->block);
+
+ rules = NULL;
+ if (ccd_selector_is_type (selector)) {
+ rules = info->type_rules;
+ } else if (ccd_selector_is_class (selector)) {
+ rules = info->class_rules;
+ } else if (ccd_selector_is_id (selector)) {
+ rules = info->id_rules;
+ } else {
+ g_assert_not_reached ();
+ }
+
+ key = ccd_selector_get_key (selector);
+ g_assert (key);
+
+ group = (ccd_selector_group_t *) g_hash_table_lookup (rules, key);
+ if (!group) {
+ group = ccd_selector_group_new ();
+ g_hash_table_insert (rules, (char *) key, group);
+ }
+ ccd_selector_group_add_selector (group, selector);
+ }
+ } while (NULL != (iter = iter->next));
+
+ info->block = NULL;
+}
+
+GSList *
+ccd_parser_parse_file (char const *css_file,
+ GHashTable *type_rules,
+ GHashTable *class_rules,
+ GHashTable *id_rules)
+{
+ CRParser *parser;
+ CRDocHandler *handler;
+ ccd_parser_info_t info;
+ enum CRStatus ret;
+
+ g_assert (css_file && type_rules && class_rules && id_rules);
+
+ parser = cr_parser_new_from_file ((guchar *) css_file, CR_UTF_8);
+
+ handler = cr_doc_handler_new ();
+ handler->app_data = (gpointer) &info;
+ info.blocks = NULL;
+ info.type_rules = type_rules;
+ info.class_rules = class_rules;
+ info.id_rules = id_rules;
+ info.block = NULL;
+
+ handler->start_selector = start_selector_cb;
+ handler->property = property_cb;
+ handler->end_selector = end_selector_cb;
+
+ cr_parser_set_sac_handler (parser, handler);
+ ret = cr_parser_parse (parser);
+
+ cr_doc_handler_destroy (handler);
+ cr_parser_destroy (parser);
+
+ return info.blocks;
+}
+
+GSList *
+ccd_parser_parse_buffer (char const *buffer,
+ size_t size,
+ GHashTable *type_rules,
+ GHashTable *class_rules,
+ GHashTable *id_rules)
+{
+ CRParser *parser;
+ CRDocHandler *handler;
+ ccd_parser_info_t info;
+ enum CRStatus ret;
+
+ g_assert (buffer && size && type_rules && class_rules && id_rules);
+
+ parser = cr_parser_new_from_buf ((guchar *) buffer, (gulong) size,
+ CR_UTF_8, false);
+
+ handler = cr_doc_handler_new ();
+ handler->app_data = (gpointer) &info;
+ info.blocks = NULL;
+ info.type_rules = type_rules;
+ info.class_rules = class_rules;
+ info.id_rules = id_rules;
+ info.block = NULL;
+
+ handler->start_selector = start_selector_cb;
+ handler->property = property_cb;
+ handler->end_selector = end_selector_cb;
+
+ cr_parser_set_sac_handler (parser, handler);
+ ret = cr_parser_parse (parser);
+
+ cr_doc_handler_destroy (handler);
+ cr_parser_destroy (parser);
+
+ return info.blocks;
+}
+
Added: bzr-playground/libccd/ccd/ccd-parser.h
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-parser.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,39 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_PARSER_H
+#define CCD_PARSER_H
+
+#include <stdbool.h>
+#include <glib.h>
+#include <ccd/ccd-features.h>
+
+G_BEGIN_DECLS
+
+GSList * ccd_parser_parse_buffer (char const *buffer, size_t size,
+ GHashTable *type_rules,
+ GHashTable *class_rules, GHashTable *id_rules);
+
+GSList * ccd_parser_parse_file (char const *css_file, GHashTable *type_rules,
+ GHashTable *class_rules, GHashTable *id_rules);
+
+G_END_DECLS
+
+#endif /* CCD_PARSER_H */
+
Added: bzr-playground/libccd/ccd/ccd-property.c
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-property.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,39 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include "ccd-property.h"
+
+ccd_property_spec_t
+ccd_property_parse_type (CRTerm const *value)
+{
+ char const *str;
+
+ if (TERM_IDENT == value->type) {
+ str = cr_string_peek_raw_str (value->content.str);
+ if (0 == strcmp ("none", str)) {
+ return CCD_PROPERTY_SPEC_NONE;
+ } else if (0 == strcmp ("inherit", str)) {
+ return CCD_PROPERTY_SPEC_INHERIT;
+ }
+ }
+
+ return CCD_PROPERTY_SPEC_UNKNOWN;
+}
+
Added: bzr-playground/libccd/ccd/ccd-property.h
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-property.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,41 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_PROPERTY_H
+#define CCD_PROPERTY_H
+
+#include <glib.h>
+#include <libcroco/libcroco.h>
+#include <ccd/ccd-features.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+ CCD_PROPERTY_SPEC_UNKNOWN = 0,
+ CCD_PROPERTY_SPEC_NONE,
+ CCD_PROPERTY_SPEC_INHERIT, /* not implemented yet */
+ CCD_PROPERTY_SPEC_SPECIFIC
+} ccd_property_spec_t;
+
+ccd_property_spec_t ccd_property_parse_type (CRTerm const *value);
+
+G_END_DECLS
+
+#endif /* CCD_PROPERTY_H */
+
Added: bzr-playground/libccd/ccd/ccd-selector-group-priv.h
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-selector-group-priv.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,53 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_SELECTOR_GROUP_PRIV_H
+#define CCD_SELECTOR_GROUP_PRIV_H
+
+#include <stdbool.h>
+#include <glib.h>
+#include <ccd/ccd-features.h>
+#include <ccd/ccd-node.h>
+#include <ccd/ccd-selector-group.h>
+#include <ccd/ccd-selector.h>
+#include <ccd/ccd-style.h>
+
+G_BEGIN_DECLS
+
+void ccd_selector_group_add_selector (ccd_selector_group_t *self,
+ ccd_selector_t *selector);
+void ccd_selector_group_merge (ccd_selector_group_t *self,
+ ccd_selector_group_t const *group);
+void ccd_selector_group_merge_base (ccd_selector_group_t *self,
+ ccd_selector_group_t const *group);
+
+GSList const * ccd_selector_group_get_dangling_selectors (ccd_selector_group_t const *self);
+void ccd_selector_group_clear_dangling_selectors (ccd_selector_group_t *self);
+
+bool ccd_selector_group_query_collect (ccd_selector_group_t const *self,
+ ccd_node_t const *node,
+ ccd_selector_group_t *result_group,
+ bool as_base);
+bool ccd_selector_group_query_apply (ccd_selector_group_t const *self,
+ ccd_node_t const *node, ccd_style_t *style);
+
+G_END_DECLS
+
+#endif /* CCD_SELECTOR_GROUP_PRIV_H */
+
Added: bzr-playground/libccd/ccd/ccd-selector-group.c
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-selector-group.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,436 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ccd-selector-group-priv.h"
+
+typedef struct {
+ GSList *selectors;
+} ccd_selector_set_t;
+
+/**
+ * ccd_selector_group_t:
+ * @sets:
+ * @min_specificity_e:
+ * @dangling_selectors:
+ *
+ * Represents a set of associated styling information.
+ **/
+struct ccd_selector_group_ {
+ GTree *sets;
+ unsigned int min_specificity_e;
+ GSList *dangling_selectors;
+};
+
+static int
+compare (size_t key1,
+ size_t key2,
+ void *data)
+{
+ return key1 - key2;
+}
+
+static void
+free_set (ccd_selector_set_t *set)
+{
+ GSList *iter;
+ ccd_selector_t *selector;
+
+ g_assert (set);
+
+ iter = set->selectors;
+ while (iter) {
+ selector = (ccd_selector_t *) iter->data;
+ iter = g_slist_remove (iter, selector);
+ ccd_selector_free (selector);
+ }
+
+ g_free (set);
+}
+
+/**
+ * ccd_selector_group_new:
+ *
+ * Create an empty selector group.
+ *
+ * A newly allocated #ccd_selector_group_t.
+ **/
+ccd_selector_group_t *
+ccd_selector_group_new (void)
+{
+ ccd_selector_group_t *self;
+
+ self = g_new0 (ccd_selector_group_t, 1);
+ self->sets = g_tree_new_full ((GCompareDataFunc) compare, NULL, NULL,
+ (GDestroyNotify) free_set);
+
+ self->min_specificity_e = CCD_SELECTOR_MAX_SPECIFICITY;
+
+ return self;
+}
+
+/**
+ * ccd_selector_group_free:
+ * @self: a #ccd_selector_group_t.
+ *
+ * Free the selector group and all associated resources.
+ **/
+void
+ccd_selector_group_free (ccd_selector_group_t *self)
+{
+ g_assert (self);
+
+ g_tree_destroy (self->sets);
+ g_free (self);
+}
+
+/*
+ * The attribute `min_specificity_e' is decremented before each recursive
+ * invocation, so base styles are cascaded root-first.
+ */
+static void
+query_base_r (ccd_selector_group_t *self,
+ ccd_node_t const *node)
+{
+ ccd_node_class_t const *node_class;
+ ccd_selector_t *selector;
+ ccd_node_t *base;
+ char const *type_name;
+ unsigned int specificity_e;
+
+ g_assert (self->min_specificity_e >= 0);
+
+ node_class = ccd_node_get_class ();
+
+ specificity_e = self->min_specificity_e;
+ base = node_class->get_base_style (node);
+ if (base) {
+ /* recurse */
+ g_assert (self->min_specificity_e > 0);
+ self->min_specificity_e--;
+ query_base_r (self, base);
+ node_class->release (base);
+ }
+
+ /* create dangling base type selector and remember for later fixup */
+ type_name = node_class->get_type (node);
+ selector = ccd_base_type_selector_new (type_name, specificity_e);
+ self->dangling_selectors = g_slist_prepend (self->dangling_selectors, selector);
+}
+
+/*
+ * Takes ownership of the selector.
+ */
+void
+ccd_selector_group_add_selector (ccd_selector_group_t *self,
+ ccd_selector_t *selector)
+{
+ ccd_selector_set_t *set;
+ size_t specificity;
+
+ g_return_if_fail (self && selector);
+
+ /* insert or update the selector group */
+ specificity = ccd_selector_get_specificity (selector);
+ set = g_tree_lookup (self->sets, GSIZE_TO_POINTER (specificity));
+ if (!set) {
+ set = g_new0 (ccd_selector_set_t, 1);
+ g_tree_insert (self->sets, GSIZE_TO_POINTER (specificity), set);
+ }
+ set->selectors = g_slist_prepend (set->selectors, selector);
+}
+
+static unsigned int
+calculate_min_specificity_e (ccd_selector_group_t *group,
+ unsigned int n_specificities)
+{
+ unsigned int specificity_e;
+
+ /* The tree is walked in order, so we remember how many
+ * specificities `e' will be required to insert the merged selectors at
+ * the right place. `- 1' because "group->min_specificity_e" already has
+ * the next free value. */
+ g_assert (((signed) group->min_specificity_e - (signed) n_specificities - 1) >= 0);
+ specificity_e = group->min_specificity_e - n_specificities - 1;
+
+ group->min_specificity_e -= n_specificities;
+ g_assert (group->min_specificity_e >= 0);
+
+ return specificity_e;
+}
+
+typedef struct {
+ ccd_selector_group_t *self;
+ bool as_base;
+ unsigned int specificity_e;
+} traverse_merge_info_t;
+
+static bool
+traverse_merge (size_t specificity,
+ ccd_selector_set_t const *set,
+ traverse_merge_info_t *info)
+{
+ GSList const *iter;
+ ccd_selector_t const *selector;
+ ccd_selector_t *new_selector;
+
+ g_assert (info->self && set);
+
+ iter = set->selectors;
+ while (iter) {
+ selector = (ccd_selector_t const *) iter->data;
+ if (info->as_base) {
+ new_selector = ccd_selector_copy_as_base (selector, info->specificity_e);
+ } else {
+ new_selector = ccd_selector_copy (selector);
+ }
+ ccd_selector_group_add_selector (info->self, new_selector);
+ iter = iter->next;
+ }
+
+ info->specificity_e++;
+
+ return false;
+}
+
+void
+ccd_selector_group_merge (ccd_selector_group_t *self,
+ ccd_selector_group_t const *group)
+{
+ traverse_merge_info_t info;
+
+ g_assert (self && group);
+
+ info.self = self;
+ info.as_base = false;
+ info.specificity_e = 0;
+ g_tree_foreach (group->sets, (GTraverseFunc) traverse_merge, &info);
+}
+
+void
+ccd_selector_group_merge_base (ccd_selector_group_t *self,
+ ccd_selector_group_t const *group)
+{
+ traverse_merge_info_t info;
+
+ g_assert (self && group);
+
+ info.self = self;
+ info.as_base = true;
+ info.specificity_e = calculate_min_specificity_e (self, g_tree_nnodes (group->sets));
+
+ g_tree_foreach (group->sets, (GTraverseFunc) traverse_merge, &info);
+}
+
+GSList const *
+ccd_selector_group_get_dangling_selectors (ccd_selector_group_t const *self)
+{
+ g_assert (self);
+
+ return self->dangling_selectors;
+}
+
+void
+ccd_selector_group_clear_dangling_selectors (ccd_selector_group_t *self)
+{
+ ccd_selector_t *selector;
+ GSList *iter;
+
+ g_return_if_fail (self && self->dangling_selectors);
+
+ iter = self->dangling_selectors;
+ while (iter) {
+ selector = (ccd_selector_t *) iter->data;
+ iter = g_slist_remove (iter, selector);
+ ccd_selector_free (selector);
+ }
+
+ self->dangling_selectors = NULL;
+}
+
+typedef struct {
+ ccd_node_t const *node;
+ ccd_selector_group_t *result_group;
+ bool as_base;
+ unsigned int specificity_e;
+ bool ret;
+} traverse_query_info_t;
+
+static bool
+traverse_query (size_t specificity,
+ ccd_selector_set_t *set,
+ traverse_query_info_t *info)
+{
+ ccd_selector_t const *selector;
+ ccd_selector_t *new_selector;
+ GSList const *iter;
+ bool ret;
+
+ iter = set->selectors;
+ while (iter) {
+ selector = (ccd_selector_t const *) iter->data;
+ ret = ccd_selector_query_apply (selector, info->node, NULL);
+ if (ret) {
+ if (info->as_base) {
+ new_selector = ccd_selector_copy_as_base (selector, info->specificity_e);
+ } else {
+ new_selector = ccd_selector_copy (selector);
+ }
+ ccd_selector_group_add_selector (info->result_group, new_selector);
+ info->specificity_e++;
+ info->ret = true;
+ }
+ iter = iter->next;
+ }
+
+ return false;
+}
+
+bool
+ccd_selector_group_query_collect (ccd_selector_group_t const *self,
+ ccd_node_t const *node,
+ ccd_selector_group_t *result_group,
+ bool as_base)
+{
+ traverse_query_info_t info;
+
+ g_assert (self && self->sets && node && result_group);
+
+ info.node = node;
+ info.result_group = result_group;
+ info.as_base = as_base;
+ info.specificity_e = calculate_min_specificity_e (result_group, g_tree_nnodes (self->sets));
+ info.ret = false;
+
+ g_tree_foreach (self->sets, (GTraverseFunc) traverse_query, &info);
+
+ return info.ret;
+}
+
+typedef struct {
+ ccd_node_t const *node;
+ ccd_style_t *style;
+ bool ret;
+} traverse_match_info_t;
+
+static bool
+traverse_match (size_t specificity,
+ ccd_selector_set_t *set,
+ traverse_match_info_t *info)
+{
+ GSList const *iter;
+
+ iter = set->selectors;
+ while (iter) {
+ info->ret |= ccd_selector_query_apply ((ccd_selector_t const *) iter->data,
+ info->node, info->style);
+ iter = iter->next;
+ }
+
+ return false;
+}
+
+bool
+ccd_selector_group_query_apply (ccd_selector_group_t const *self,
+ ccd_node_t const *node,
+ ccd_style_t *style)
+{
+ traverse_match_info_t info;
+
+ g_assert (self && self->sets && node && style);
+
+ info.node = node;
+ info.style = style;
+ info.ret = false;
+
+ g_tree_foreach (self->sets, (GTraverseFunc) traverse_match, &info);
+
+ return info.ret;
+}
+
+static bool
+traverse_apply (size_t specificity,
+ ccd_selector_set_t *set,
+ ccd_style_t *style)
+{
+ GSList const *iter;
+
+ iter = set->selectors;
+ while (iter) {
+ ccd_selector_apply ((ccd_selector_t const *) iter->data, style);
+ iter = iter->next;
+ }
+
+ return false;
+}
+
+/**
+ * ccd_selector_group_apply:
+ * @self: a #ccd_selector_group_t.
+ * @style: a #ccd_style_t.
+ *
+ * Apply the styling information held by #self to #style.
+ **/
+void
+ccd_selector_group_apply (ccd_selector_group_t const *self,
+ ccd_style_t *style)
+{
+ g_assert (self && self->sets && style);
+
+ g_tree_foreach (self->sets, (GTraverseFunc) traverse_apply, style);
+}
+
+static bool
+traverse_dump (size_t specificity,
+ ccd_selector_set_t *set,
+ void *data)
+{
+ GSList const *iter;
+
+ iter = set->selectors;
+ while (iter) {
+ ccd_selector_dump ((ccd_selector_t const *) iter->data);
+ iter = iter->next;
+ }
+
+ return false;
+}
+
+/**
+ * ccd_selector_group_dump:
+ * @self: a ccd_selector_group_t.
+ *
+ * Print informations about the internal state of this object.
+ **/
+void
+ccd_selector_group_dump (ccd_selector_group_t const *self)
+{
+ GSList const *iter;
+
+ g_return_if_fail (self);
+
+ g_tree_foreach (self->sets, (GTraverseFunc) traverse_dump, NULL);
+
+ iter = self->dangling_selectors;
+ while (iter) {
+ printf ("(dangling) ");
+ ccd_selector_dump ((ccd_selector_t const *) iter->data);
+ iter = iter->next;
+ }
+}
+
Added: bzr-playground/libccd/ccd/ccd-selector-group.h
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-selector-group.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,45 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_SELECTOR_GROUP_H
+#define CCD_SELECTOR_GROUP_H
+
+#include <stdbool.h>
+#include <glib.h>
+#include <ccd/ccd-features.h>
+#include <ccd/ccd-node.h>
+#include <ccd/ccd-selector.h>
+#include <ccd/ccd-style.h>
+
+G_BEGIN_DECLS
+
+typedef struct ccd_selector_group_ ccd_selector_group_t;
+
+ccd_selector_group_t * ccd_selector_group_new (void);
+void ccd_selector_group_free (ccd_selector_group_t *self);
+
+void ccd_selector_group_apply (ccd_selector_group_t const *self,
+ ccd_style_t *style);
+
+void ccd_selector_group_dump (ccd_selector_group_t const *self);
+
+G_END_DECLS
+
+#endif /* CCD_SELECTOR_GROUP_H */
+
Added: bzr-playground/libccd/ccd/ccd-selector.c
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-selector.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,913 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "ccd-node.h"
+#include "ccd-selector.h"
+#include "ccd-style.h"
+#include "ccd-stylesheet.h"
+
+typedef enum {
+ CCD_SELECTOR_MODALITY_UNIVERSAL, /* Universal selector. */
+ CCD_SELECTOR_MODALITY_TYPE, /* By element type. */
+ CCD_SELECTOR_MODALITY_BASE_TYPE, /* By element type. */
+ CCD_SELECTOR_MODALITY_CLASS, /* By element class. */
+ CCD_SELECTOR_MODALITY_ID, /* By element ID. */
+ CCD_SELECTOR_MODALITY_ATTRIBUTE, /* By element attribute. */
+ CCD_SELECTOR_MODALITY_PSEUDO_CLASS /* By pseudo class. */
+} ccd_selector_modality_t;
+
+/*
+ * Abstract base selector.
+ * See http://www.w3.org/TR/CSS21/cascade.html#specificity for an explantion
+ * of the meaning of the fields `a', `b', `c' and `d'. Field `e' (lowest priority)
+ * is used for merging base styles. Field `a' is not used currently.
+ */
+struct ccd_selector_ {
+ ccd_selector_modality_t modality;
+ uint8_t a;
+ uint8_t b;
+ uint8_t c;
+ uint8_t d;
+ uint8_t e;
+ struct ccd_selector_ *refinement;
+ struct ccd_selector_ *container;
+ ccd_block_t const *block;
+};
+
+static void
+selector_sync (ccd_selector_t const *self,
+ ccd_selector_t *to)
+{
+ g_assert (self && to);
+
+ to->modality = self->modality;
+ to->a = self->a;
+ to->b = self->b;
+ to->c = self->c;
+ to->d = self->d;
+ to->e = self->e;
+ to->refinement = NULL;
+ to->container = NULL;
+ to->block = self->block;
+}
+
+/*
+ * Universal selector.
+ */
+typedef ccd_selector_t ccd_universal_selector_t;
+
+ccd_selector_t *
+ccd_universal_selector_new (void)
+{
+ ccd_universal_selector_t *self;
+
+ self = g_new0 (ccd_universal_selector_t, 1);
+ self->modality = CCD_SELECTOR_MODALITY_UNIVERSAL;
+
+ return (ccd_selector_t *) self;
+}
+
+static ccd_selector_t *
+universal_selector_dup (ccd_universal_selector_t const *original)
+{
+ ccd_universal_selector_t *self;
+
+ self = g_new0 (ccd_universal_selector_t, 1);
+ selector_sync ((ccd_selector_t const *) original, self);
+
+ return (ccd_selector_t *) self;
+}
+
+static void
+universal_selector_free (ccd_universal_selector_t *self)
+{
+ g_assert (self);
+
+ g_free (self);
+}
+
+static void
+universal_selector_dump (ccd_universal_selector_t const *self)
+{
+ printf (" *");
+}
+
+/*
+ * Select by element type.
+ */
+typedef struct {
+ ccd_selector_t parent;
+ char *type_name;
+} ccd_type_selector_t;
+
+ccd_selector_t *
+ccd_type_selector_new (char const *type_name)
+{
+ ccd_type_selector_t *self;
+
+ g_assert (type_name);
+
+ self = g_new0 (ccd_type_selector_t, 1);
+ self->parent.modality = CCD_SELECTOR_MODALITY_TYPE;
+ self->parent.d = 1;
+ self->type_name = g_strdup (type_name);
+
+ return (ccd_selector_t *) self;
+}
+
+static ccd_selector_t *
+type_selector_dup (ccd_type_selector_t const *original)
+{
+ ccd_type_selector_t *self;
+
+ self = g_new0 (ccd_type_selector_t, 1);
+ selector_sync ((ccd_selector_t const *) original, &self->parent);
+ self->type_name = g_strdup (original->type_name);
+
+ return (ccd_selector_t *) self;
+}
+
+static void
+type_selector_free (ccd_type_selector_t *self)
+{
+ g_assert (self);
+
+ g_free (self->type_name);
+ g_free (self);
+}
+
+static void
+type_selector_dump (ccd_type_selector_t const *self)
+{
+ printf (" %s", self->type_name);
+}
+
+/*
+ * Select by element's base type.
+ * Derived from the type selector
+ */
+ccd_selector_t *
+ccd_base_type_selector_new (char const *type_name,
+ unsigned int specificity_e)
+{
+ ccd_selector_t *self;
+
+ self = ccd_type_selector_new (type_name);
+ self->modality = CCD_SELECTOR_MODALITY_BASE_TYPE;
+ self->a = 0;
+ self->b = 0;
+ self->c = 0;
+ self->d = 0;
+ self->e = specificity_e;
+
+ return self;
+}
+
+/*
+ * Select by element class.
+ */
+typedef struct {
+ ccd_selector_t parent;
+ char *class_name;
+} ccd_class_selector_t;
+
+ccd_selector_t *
+ccd_class_selector_new (char const *class_name)
+{
+ ccd_class_selector_t *self;
+
+ g_assert (class_name);
+
+ self = g_new0 (ccd_class_selector_t, 1);
+ self->parent.modality = CCD_SELECTOR_MODALITY_CLASS;
+ self->parent.c = 1;
+ self->class_name = g_strdup (class_name);
+
+ return (ccd_selector_t *) self;
+}
+
+static ccd_selector_t *
+class_selector_dup (ccd_class_selector_t const *original)
+{
+ ccd_class_selector_t *self;
+
+ self = g_new0 (ccd_class_selector_t, 1);
+ selector_sync ((ccd_selector_t const *) original, &self->parent);
+ self->class_name = g_strdup (original->class_name);
+
+ return (ccd_selector_t *) self;
+}
+
+static void
+class_selector_free (ccd_class_selector_t *self)
+{
+ g_assert (self);
+
+ g_free (self->class_name);
+ g_free (self);
+}
+
+static void
+class_selector_dump (ccd_class_selector_t const *self)
+{
+ printf (".%s", self->class_name);
+}
+
+/*
+ * Select by element ID.
+ */
+typedef struct {
+ ccd_selector_t parent;
+ char *id;
+} ccd_id_selector_t;
+
+ccd_selector_t *
+ccd_id_selector_new (char const *id)
+{
+ ccd_id_selector_t *self;
+
+ g_assert (id);
+
+ self = g_new0 (ccd_id_selector_t, 1);
+ self->parent.modality = CCD_SELECTOR_MODALITY_ID;
+ self->parent.b = 1;
+ self->id = g_strdup (id);
+
+ return (ccd_selector_t *) self;
+}
+
+static ccd_selector_t *
+id_selector_dup (ccd_id_selector_t const *original)
+{
+ ccd_id_selector_t *self;
+
+ self = g_new0 (ccd_id_selector_t, 1);
+ selector_sync ((ccd_selector_t const *) original, &self->parent);
+ self->id = g_strdup (original->id);
+
+ return (ccd_selector_t *) self;
+}
+
+static void
+id_selector_free (ccd_id_selector_t *self)
+{
+ g_assert (self);
+
+ g_free (self->id);
+ g_free (self);
+}
+
+static void
+id_selector_dump (ccd_id_selector_t const *self)
+{
+ printf ("#%s", self->id);
+}
+
+/*
+ * Select by attribute.
+ */
+typedef struct {
+ ccd_selector_t parent;
+ char *name;
+ char *value;
+ ccd_attribute_selector_match_t match;
+} ccd_attribute_selector_t;
+
+ccd_selector_t *
+ccd_attribute_selector_new (char const *name,
+ char const *value,
+ ccd_attribute_selector_match_t match)
+{
+ ccd_attribute_selector_t *self;
+
+ g_assert (name && value);
+
+ self = g_new0 (ccd_attribute_selector_t, 1);
+ self->parent.modality = CCD_SELECTOR_MODALITY_ATTRIBUTE;
+ self->name = g_strdup (name);
+ self->value = g_strdup (value);
+ self->match = match;
+
+ return (ccd_selector_t *) self;
+}
+
+static ccd_selector_t *
+attribute_selector_dup (ccd_attribute_selector_t const *original)
+{
+ ccd_attribute_selector_t *self;
+
+ self = g_new0 (ccd_attribute_selector_t, 1);
+ selector_sync ((ccd_selector_t const *) original, &self->parent);
+ self->name = g_strdup (original->name);
+ self->value = g_strdup (original->value);
+ self->match = original->match;
+
+ return (ccd_selector_t *) self;
+}
+
+static void
+attribute_selector_free (ccd_attribute_selector_t *self)
+{
+ g_assert (self);
+
+ g_free (self->name);
+ g_free (self->value);
+ g_free (self);
+}
+
+static void
+attribute_selector_dump (ccd_attribute_selector_t const *self)
+{
+ switch (self->match) {
+ case CCD_ATTRIBUTE_SELECTOR_MATCH_EXISTS:
+ printf ("[%s]", self->name);
+ break;
+ case CCD_ATTRIBUTE_SELECTOR_MATCH_EQUALS:
+ printf ("[%s=%s]", self->name, self->value);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+/*
+ * Select by pseudo class.
+ */
+typedef struct {
+ ccd_selector_t parent;
+ char *pseudo_class;
+} ccd_pseudo_class_selector_t;
+
+ccd_selector_t *
+ccd_pseudo_class_selector_new (char const *pseudo_class)
+{
+ ccd_pseudo_class_selector_t *self;
+
+ g_assert (pseudo_class);
+
+ self = g_new0 (ccd_pseudo_class_selector_t, 1);
+ self->parent.modality = CCD_SELECTOR_MODALITY_PSEUDO_CLASS;
+ self->pseudo_class = g_strdup (pseudo_class);
+
+ return (ccd_selector_t *) self;
+}
+
+static ccd_selector_t *
+pseudo_class_selector_dup (ccd_pseudo_class_selector_t const *original)
+{
+ ccd_pseudo_class_selector_t *self;
+
+ self = g_new0 (ccd_pseudo_class_selector_t, 1);
+ selector_sync ((ccd_selector_t const *) original, &self->parent);
+ self->pseudo_class = g_strdup (original->pseudo_class);
+
+ return (ccd_selector_t *) self;
+}
+
+static void
+pseudo_class_selector_free (ccd_pseudo_class_selector_t *self)
+{
+ g_assert (self);
+
+ g_free (self->pseudo_class);
+ g_free (self);
+}
+
+static void
+pseudo_class_selector_dump (ccd_pseudo_class_selector_t const *self)
+{
+ printf (":%s", self->pseudo_class);
+}
+
+ccd_selector_t *
+ccd_selector_copy (ccd_selector_t const *original)
+{
+ ccd_selector_t *self;
+
+ g_assert (original);
+
+ switch (original->modality) {
+ case CCD_SELECTOR_MODALITY_UNIVERSAL:
+ self = universal_selector_dup ((ccd_universal_selector_t const *) original);
+ break;
+ case CCD_SELECTOR_MODALITY_TYPE:
+ case CCD_SELECTOR_MODALITY_BASE_TYPE:
+ self = type_selector_dup ((ccd_type_selector_t const *) original);
+ break;
+ case CCD_SELECTOR_MODALITY_CLASS:
+ self = class_selector_dup ((ccd_class_selector_t const *) original);
+ break;
+ case CCD_SELECTOR_MODALITY_ID:
+ self = id_selector_dup ((ccd_id_selector_t const *) original);
+ break;
+ case CCD_SELECTOR_MODALITY_ATTRIBUTE:
+ self = attribute_selector_dup ((ccd_attribute_selector_t const *) original);
+ break;
+ case CCD_SELECTOR_MODALITY_PSEUDO_CLASS:
+ self = pseudo_class_selector_dup ((ccd_pseudo_class_selector_t const *) original);
+ break;
+ default:
+ g_warning ("Unknown selector modality %d", original->modality);
+ self = NULL;
+ return self;
+ }
+
+ if (original->refinement) {
+ self->refinement = ccd_selector_copy (original->refinement);
+ }
+
+ if (original->container) {
+ self->container = ccd_selector_copy (original->container);
+ }
+
+ return self;
+}
+
+/*
+ * Create a selector based on an existing one.
+ */
+ccd_selector_t *
+ccd_selector_copy_as_base (ccd_selector_t const *original,
+ int specificity_e)
+{
+ ccd_selector_t *self;
+
+ g_assert (original && original->modality == CCD_SELECTOR_MODALITY_TYPE);
+
+ self = ccd_selector_copy (original);
+ self->modality = CCD_SELECTOR_MODALITY_BASE_TYPE;
+
+ if (specificity_e > -1) {
+ if (original->d > 0) {
+ self->d--;
+ } else {
+ g_warning ("Specificity d == 0");
+ }
+
+ if (original->e == 0) {
+ g_assert (specificity_e <= CCD_SELECTOR_MAX_SPECIFICITY);
+ self->e = (unsigned) specificity_e;
+ } else {
+ g_warning ("Specificity e != 0");
+ }
+ }
+
+ return self;
+}
+
+/*
+ * Free the whole selector chain.
+ */
+void
+ccd_selector_free (ccd_selector_t *self)
+{
+ g_assert (self);
+
+ if (self->container) {
+ ccd_selector_free (self->container), self->container = NULL;
+ }
+
+ if (self->refinement) {
+ ccd_selector_free (self->refinement), self->refinement = NULL;
+ }
+
+ switch (self->modality) {
+ case CCD_SELECTOR_MODALITY_UNIVERSAL:
+ universal_selector_free ((ccd_universal_selector_t *) self);
+ break;
+ case CCD_SELECTOR_MODALITY_TYPE:
+ case CCD_SELECTOR_MODALITY_BASE_TYPE:
+ type_selector_free ((ccd_type_selector_t *) self);
+ break;
+ case CCD_SELECTOR_MODALITY_CLASS:
+ class_selector_free ((ccd_class_selector_t *) self);
+ break;
+ case CCD_SELECTOR_MODALITY_ID:
+ id_selector_free ((ccd_id_selector_t *) self);
+ break;
+ case CCD_SELECTOR_MODALITY_ATTRIBUTE:
+ attribute_selector_free ((ccd_attribute_selector_t *) self);
+ break;
+ case CCD_SELECTOR_MODALITY_PSEUDO_CLASS:
+ pseudo_class_selector_free ((ccd_pseudo_class_selector_t *) self);
+ break;
+ default:
+ g_warning ("Unknown selector modality %d", self->modality);
+ }
+}
+
+/*
+ * Does it matter that the refinements order is reversed?
+ */
+void
+ccd_selector_refine (ccd_selector_t *self,
+ ccd_selector_t *selector)
+{
+ g_assert (self && selector);
+
+ selector->refinement = self->refinement;
+ self->refinement = selector;
+
+ switch (selector->modality) {
+ case CCD_SELECTOR_MODALITY_CLASS:
+ g_assert (selector->c < CCD_SELECTOR_MAX_SPECIFICITY);
+ self->c++;
+ break;
+ case CCD_SELECTOR_MODALITY_ID:
+ g_assert (selector->b < CCD_SELECTOR_MAX_SPECIFICITY);
+ self->b++;
+ break;
+ case CCD_SELECTOR_MODALITY_ATTRIBUTE:
+ g_assert (selector->c < CCD_SELECTOR_MAX_SPECIFICITY);
+ self->c++;
+ break;
+ case CCD_SELECTOR_MODALITY_PSEUDO_CLASS:
+ g_assert (selector->d < CCD_SELECTOR_MAX_SPECIFICITY);
+ self->d++;
+ break;
+ case CCD_SELECTOR_MODALITY_UNIVERSAL:
+ case CCD_SELECTOR_MODALITY_TYPE:
+ case CCD_SELECTOR_MODALITY_BASE_TYPE:
+ default:
+ g_warning ("Invalid selector modality %d", self->modality);
+ }
+}
+
+/*
+ * Add a selector to the chain.
+ * This can change the selector instance, make sure to regard the return value.
+ */
+ccd_selector_t *
+ccd_selector_append (ccd_selector_t *self,
+ ccd_selector_t *selector)
+{
+ g_assert (self && selector);
+
+ selector->container = self;
+
+ /* propagate specificity */
+ selector->a = self->a;
+ selector->b = self->b;
+ selector->c = self->c;
+ selector->d = self->d;
+ selector->e = self->e;
+
+ /* update specificity */
+ switch (self->modality) {
+ case CCD_SELECTOR_MODALITY_UNIVERSAL:
+ /* no weight */
+ break;
+ case CCD_SELECTOR_MODALITY_TYPE:
+ g_assert (selector->d < CCD_SELECTOR_MAX_SPECIFICITY);
+ selector->d++;
+ break;
+ case CCD_SELECTOR_MODALITY_BASE_TYPE:
+ case CCD_SELECTOR_MODALITY_CLASS:
+ case CCD_SELECTOR_MODALITY_ID:
+ case CCD_SELECTOR_MODALITY_ATTRIBUTE:
+ case CCD_SELECTOR_MODALITY_PSEUDO_CLASS:
+ default:
+ g_warning ("Invalid selector modality %d", self->modality);
+ }
+
+ return selector;
+}
+
+bool
+ccd_selector_is_type (ccd_selector_t const *self)
+{
+ switch (self->modality) {
+ case CCD_SELECTOR_MODALITY_UNIVERSAL:
+ case CCD_SELECTOR_MODALITY_TYPE:
+ return true;
+ case CCD_SELECTOR_MODALITY_BASE_TYPE:
+ case CCD_SELECTOR_MODALITY_CLASS:
+ case CCD_SELECTOR_MODALITY_ID:
+ case CCD_SELECTOR_MODALITY_ATTRIBUTE:
+ case CCD_SELECTOR_MODALITY_PSEUDO_CLASS:
+ default:
+ return false;
+ }
+}
+
+bool
+ccd_selector_is_class (ccd_selector_t const *self)
+{
+ switch (self->modality) {
+ case CCD_SELECTOR_MODALITY_CLASS:
+ return true;
+ case CCD_SELECTOR_MODALITY_UNIVERSAL:
+ case CCD_SELECTOR_MODALITY_TYPE:
+ case CCD_SELECTOR_MODALITY_BASE_TYPE:
+ case CCD_SELECTOR_MODALITY_ID:
+ case CCD_SELECTOR_MODALITY_ATTRIBUTE:
+ case CCD_SELECTOR_MODALITY_PSEUDO_CLASS:
+ default:
+ return false;
+ }
+}
+
+bool
+ccd_selector_is_id (ccd_selector_t const *self)
+{
+ switch (self->modality) {
+ case CCD_SELECTOR_MODALITY_ID:
+ return true;
+ case CCD_SELECTOR_MODALITY_UNIVERSAL:
+ case CCD_SELECTOR_MODALITY_TYPE:
+ case CCD_SELECTOR_MODALITY_BASE_TYPE:
+ case CCD_SELECTOR_MODALITY_CLASS:
+ case CCD_SELECTOR_MODALITY_ATTRIBUTE:
+ case CCD_SELECTOR_MODALITY_PSEUDO_CLASS:
+ default:
+ return false;
+ }
+}
+
+ccd_block_t const *
+ccd_selector_get_block (ccd_selector_t const *self)
+{
+ g_assert (self);
+
+ return self->block;
+}
+
+void
+ccd_selector_set_block (ccd_selector_t *self,
+ ccd_block_t const *block)
+{
+ g_assert (self);
+
+ self->block = block;
+}
+
+/*
+ * Depending on the modality of the selector this may return NULL.
+ */
+char const *
+ccd_selector_get_key (ccd_selector_t const *self)
+{
+ g_return_val_if_fail (self, NULL);
+
+ switch (self->modality) {
+ case CCD_SELECTOR_MODALITY_UNIVERSAL:
+ return "*";
+ case CCD_SELECTOR_MODALITY_TYPE:
+ case CCD_SELECTOR_MODALITY_BASE_TYPE:
+ return ((ccd_type_selector_t *) self)->type_name;
+ case CCD_SELECTOR_MODALITY_CLASS:
+ return ((ccd_class_selector_t *) self)->class_name;
+ case CCD_SELECTOR_MODALITY_ID:
+ return ((ccd_id_selector_t *) self)->id;
+ case CCD_SELECTOR_MODALITY_ATTRIBUTE:
+ case CCD_SELECTOR_MODALITY_PSEUDO_CLASS:
+ default:
+ return NULL;
+ }
+}
+
+uint32_t
+ccd_selector_get_specificity (ccd_selector_t const *self)
+{
+ g_assert (self->a <= CCD_SELECTOR_MAX_SPECIFICITY &&
+ self->b <= CCD_SELECTOR_MAX_SPECIFICITY &&
+ self->c <= CCD_SELECTOR_MAX_SPECIFICITY &&
+ self->d <= CCD_SELECTOR_MAX_SPECIFICITY &&
+ self->e <= CCD_SELECTOR_MAX_SPECIFICITY);
+
+ return self->e | (self->d << 6) | (self->c << 12) | (self->b << 18) | (self->a << 24);
+}
+
+void
+ccd_selector_get_specificity_values (ccd_selector_t const *self,
+ unsigned int *a,
+ unsigned int *b,
+ unsigned int *c,
+ unsigned int *d,
+ unsigned int *e)
+{
+ g_assert (self);
+
+ if (a)
+ *a = self->a;
+
+ if (b)
+ *b = self->b;
+
+ if (c)
+ *c = self->c;
+
+ if (d)
+ *d = self->d;
+
+ if (e)
+ *e = self->e;
+}
+
+extern void dump_node (ccd_node_t const *node);
+
+/*
+ * `style' may be NULL, in which case this just tests for a match.
+ */
+bool
+ccd_selector_query_apply (ccd_selector_t const *self,
+ ccd_node_t const *node,
+ ccd_style_t *style)
+{
+ ccd_node_class_t const *node_class;
+ char const *name;
+ char const *value;
+ bool is_matching;
+
+ g_return_val_if_fail (self && node, false);
+
+ node_class = ccd_node_get_class ();
+
+ is_matching = false;
+ switch (self->modality) {
+ case CCD_SELECTOR_MODALITY_UNIVERSAL:
+ is_matching = true;
+ break;
+ case CCD_SELECTOR_MODALITY_TYPE:
+ is_matching = node_class->is_a (node, ((ccd_type_selector_t *) self)->type_name);
+ break;
+ case CCD_SELECTOR_MODALITY_BASE_TYPE:
+ /* HACK warning: let's just say it matches, because the base type selectors have
+ * been set up internally -- that is in the fixup run after loading the stylesheet. */
+ is_matching = true;
+ break;
+ case CCD_SELECTOR_MODALITY_CLASS:
+ name = node_class->get_class (node);
+ is_matching = name ? 0 == strcmp (name, ((ccd_class_selector_t *) self)->class_name) : false;
+ break;
+ case CCD_SELECTOR_MODALITY_ID:
+ name = node_class->get_id (node);
+ is_matching = name ? 0 == strcmp (name, ((ccd_id_selector_t *) self)->id) : false;
+ break;
+ case CCD_SELECTOR_MODALITY_ATTRIBUTE:
+ name = ((ccd_attribute_selector_t *) self)->name;
+ value = node_class->get_attribute (node, name);
+ switch (((ccd_attribute_selector_t *) self)->match) {
+ case CCD_ATTRIBUTE_SELECTOR_MATCH_EXISTS:
+ is_matching = value ? true : false;
+ break;
+ case CCD_ATTRIBUTE_SELECTOR_MATCH_EQUALS:
+ is_matching = value ? 0 == strcmp (value, ((ccd_attribute_selector_t *) self)->value) : false;
+ break;
+ default:
+ g_assert_not_reached ();
+ is_matching = false;
+ }
+ break;
+ case CCD_SELECTOR_MODALITY_PSEUDO_CLASS:
+ name = node_class->get_pseudo_class (node);
+ is_matching = name ? 0 == strcmp (name, ((ccd_pseudo_class_selector_t *) self)->pseudo_class) : false;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (!is_matching) {
+ return false;
+ }
+
+ /* recursively match refinements */
+ if (self->refinement) {
+ is_matching = ccd_selector_query_apply (self->refinement, node, style);
+ if (!is_matching) {
+ return false;
+ }
+ }
+
+ /* recursively match container */
+ if (self->container) {
+ ccd_node_t *container;
+ container = node_class->get_container (node);
+ is_matching = false;
+ if (container) {
+ is_matching = ccd_selector_query_apply (self->container, container, style);
+ node_class->release (container);
+ }
+ if (!is_matching) {
+ return false;
+ }
+ }
+
+ /* merge */
+ if (self->block && style) {
+ ccd_selector_apply (self, style);
+ }
+
+ return true;
+}
+
+bool
+ccd_selector_apply (ccd_selector_t const *self,
+ ccd_style_t *style)
+{
+ g_return_val_if_fail (self && self->block && style, false);
+
+ switch (self->block->background.color_type) {
+ case CCD_PROPERTY_SPEC_UNKNOWN:
+ /* do nothing */
+ break;
+ case CCD_PROPERTY_SPEC_NONE:
+ /* reset */
+ style->background = NULL;
+ break;
+ case CCD_PROPERTY_SPEC_INHERIT:
+ /* not implemented */
+ g_assert_not_reached ();
+ break;
+ case CCD_PROPERTY_SPEC_SPECIFIC:
+ /* use */
+ style->background = &self->block->background;
+ break;
+ }
+
+ if (self->block->border.left.flags)
+ style->left = &self->block->border.left;
+ if (self->block->border.top.flags)
+ style->top = &self->block->border.top;
+ if (self->block->border.right.flags)
+ style->right = &self->block->border.right;
+ if (self->block->border.bottom.flags)
+ style->bottom = &self->block->border.bottom;
+
+ return true;
+}
+
+void
+ccd_selector_dump (ccd_selector_t const *self)
+{
+ g_assert (self);
+
+ printf ("%p: ", (void *) self);
+
+ if (self->container) {
+ ccd_selector_t const *container;
+ printf ("( ");
+ container = self->container;
+ while (container) {
+ printf("%s ", ccd_selector_get_key (container));
+ container = container->container;
+ }
+ printf (")");
+ }
+
+ switch (self->modality) {
+ case CCD_SELECTOR_MODALITY_UNIVERSAL:
+ universal_selector_dump ((ccd_universal_selector_t *) self);
+ break;
+ case CCD_SELECTOR_MODALITY_TYPE:
+ case CCD_SELECTOR_MODALITY_BASE_TYPE:
+ type_selector_dump ((ccd_type_selector_t *) self);
+ break;
+ case CCD_SELECTOR_MODALITY_CLASS:
+ class_selector_dump ((ccd_class_selector_t *) self);
+ break;
+ case CCD_SELECTOR_MODALITY_ID:
+ id_selector_dump ((ccd_id_selector_t *) self);
+ break;
+ case CCD_SELECTOR_MODALITY_ATTRIBUTE:
+ attribute_selector_dump ((ccd_attribute_selector_t *) self);
+ break;
+ case CCD_SELECTOR_MODALITY_PSEUDO_CLASS:
+ pseudo_class_selector_dump ((ccd_pseudo_class_selector_t *) self);
+ break;
+ default:
+ g_warning ("Unknown selector modality %d", self->modality);
+ }
+
+ if (self->refinement) {
+ ccd_selector_dump (self->refinement);
+ }
+
+ if (self->block) {
+ printf (" {\n");
+ ccd_block_dump (self->block);
+ printf ("}");
+ }
+
+ printf (" # modality: %d, specificity: %d,%d,%d,%d,%d\n",
+ self->modality, self->a, self->b, self->c, self->d, self->e);
+}
+
Added: bzr-playground/libccd/ccd/ccd-selector.h
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-selector.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,82 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_SELECTOR_H
+#define CCD_SELECTOR_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <glib.h>
+#include <ccd/ccd-features.h>
+#include <ccd/ccd-block.h>
+#include <ccd/ccd-node.h>
+#include <ccd/ccd-style.h>
+
+G_BEGIN_DECLS
+
+#define CCD_SELECTOR_MAX_SPECIFICITY ((1 << 5) - 1)
+
+typedef struct ccd_rule_set_ ccd_rule_set_t;
+typedef struct ccd_selector_ ccd_selector_t;
+
+typedef enum {
+ CCD_ATTRIBUTE_SELECTOR_MATCH_EXISTS,
+ CCD_ATTRIBUTE_SELECTOR_MATCH_EQUALS
+ /* more match types go here */
+} ccd_attribute_selector_match_t;
+
+ccd_selector_t * ccd_universal_selector_new (void);
+ccd_selector_t * ccd_type_selector_new (char const *type_name);
+ccd_selector_t * ccd_base_type_selector_new (char const *type_name, unsigned int specificity_e);
+ccd_selector_t * ccd_class_selector_new (char const *class_name);
+ccd_selector_t * ccd_id_selector_new (char const *id);
+ccd_selector_t * ccd_attribute_selector_new (char const *name, char const *value, ccd_attribute_selector_match_t match);
+ccd_selector_t * ccd_pseudo_class_selector_new (char const *pseudo_class);
+
+ccd_selector_t * ccd_selector_copy (ccd_selector_t const *original);
+ccd_selector_t * ccd_selector_copy_as_base (ccd_selector_t const *original,
+ int specificity_e);
+
+void ccd_selector_free (ccd_selector_t *self);
+
+void ccd_selector_refine (ccd_selector_t *self, ccd_selector_t *selector);
+ccd_selector_t * ccd_selector_append (ccd_selector_t *self, ccd_selector_t *selector);
+
+bool ccd_selector_is_type (ccd_selector_t const *self);
+bool ccd_selector_is_class (ccd_selector_t const *self);
+bool ccd_selector_is_id (ccd_selector_t const *self);
+
+ccd_block_t const * ccd_selector_get_block (ccd_selector_t const *self);
+void ccd_selector_set_block (ccd_selector_t *self, ccd_block_t const *block);
+
+char const * ccd_selector_get_key (ccd_selector_t const *self);
+uint32_t ccd_selector_get_specificity (ccd_selector_t const *self);
+void ccd_selector_get_specificity_values (ccd_selector_t const *self,
+ unsigned int *a, unsigned int *b, unsigned int *c, unsigned int *d, unsigned int *e);
+
+bool ccd_selector_query_apply (ccd_selector_t const *self, ccd_node_t const *node,
+ ccd_style_t *style);
+bool ccd_selector_apply (ccd_selector_t const *self, ccd_style_t *style);
+
+void ccd_selector_dump (ccd_selector_t const *self);
+
+G_END_DECLS
+
+#endif /* CCD_SELECTOR_H */
+
Added: bzr-playground/libccd/ccd/ccd-style.c
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-style.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,148 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include "ccd-style.h"
+
+/**
+ * ccd_style_init:
+ * @self: a ccd_style_t.
+ *
+ * Reset the object's internal state.
+ **/
+void
+ccd_style_init (ccd_style_t *self)
+{
+ memset (self, 0, sizeof (*self));
+}
+
+/**
+ * ccd_style_draw_horizontal_line:
+ * @self: a ccd_style_t.
+ * @cr: the target to draw onto.
+ * @x1: the starting x coordinate.
+ * @x2: the ending x coordinate.
+ * @y: the y coordinate.
+ *
+ * Draw a horizontal line using this style instance. This takes the `top'
+ * border from the CSS, if specified.
+ **/
+void
+ccd_style_draw_line (ccd_style_t const *self,
+ cairo_t *cr,
+ int32_t x1,
+ int32_t x2,
+ int32_t y1,
+ int32_t y2)
+{
+ double off;
+
+ if (y1 == y2) {
+ /* horizontal */
+
+ /* Unlike borders, lines are not drawn inside the box,
+ * account for that. */
+ off = self->top->width / 2.;
+
+ ccd_border_draw (NULL, self->top, NULL, NULL,
+ cr, x1, y1 - off, x2 - x1, 0);
+ } else {
+ /* vertical */
+
+ /* Unlike borders, lines are not drawn inside the box,
+ * account for that. */
+ off = self->left->width / 2.;
+
+ ccd_border_draw (self->left, NULL, NULL, NULL,
+ cr, x1 - off, y1, 0, y2 - y1);
+ }
+
+}
+
+/**
+ * ccd_style_draw_outline:
+ * @self: a ccd_style_t.
+ * @cr: the target to draw onto.
+ * @x: the starting x coordinate.
+ * @y: the starting y coordinate.
+ * @width: width of the outline to draw.
+ * @height: height of the outline to draw.
+ *
+ * Draw an outline using this style instance. Information about how to draw
+ * this style's background is diregarded.
+ **/
+void
+ccd_style_draw_outline (ccd_style_t const *self,
+ cairo_t *cr,
+ int32_t x,
+ int32_t y,
+ int32_t width,
+ int32_t height)
+{
+ ccd_border_draw (self->left, self->top, self->right, self->bottom,
+ cr, x, y, width, height);
+}
+
+/**
+ * ccd_style_draw_rectangle:
+ * @self: a ccd_style_t.
+ * @cr: the target to draw onto.
+ * @x: the starting x coordinate.
+ * @y: the starting y coordinate.
+ * @width: width of the outline to draw.
+ * @height: height of the outline to draw.
+ *
+ * Draw a rectangle using this style instance.
+ **/
+void
+ccd_style_draw_rectangle (ccd_style_t const *self,
+ cairo_t *cr,
+ int32_t x,
+ int32_t y,
+ int32_t width,
+ int32_t height)
+{
+ if (self->background) {
+ ccd_background_draw (self->background, cr, x, y, width, height);
+ }
+ ccd_border_draw (self->left, self->top, self->right, self->bottom,
+ cr, x, y, width, height);
+}
+
+/**
+ * ccd_style_dump:
+ * @self: a ccd_style_t.
+ *
+ * Print informations about the internal state of this object.
+ **/
+void
+ccd_style_dump (ccd_style_t const *self)
+{
+ if (self->background)
+ ccd_background_dump (self->background);
+ if (self->left)
+ ccd_border_dump_stroke (self->left);
+ if (self->top)
+ ccd_border_dump_stroke (self->top);
+ if (self->right)
+ ccd_border_dump_stroke (self->right);
+ if (self->bottom)
+ ccd_border_dump_stroke (self->bottom);
+}
+
Added: bzr-playground/libccd/ccd/ccd-style.h
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-style.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,65 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_STYLE_H
+#define CCD_STYLE_H
+
+#include <stdint.h>
+#include <glib.h>
+#include <cairo.h>
+#include <ccd/ccd-features.h>
+#include <ccd/ccd-background.h>
+#include <ccd/ccd-border.h>
+
+G_BEGIN_DECLS
+
+/**
+ * ccd_style_t:
+ *
+ * Representation of a block of CSS statements.
+ *
+ * <emphasis>Memory management:</emphasis> Style objects are owned by the
+ * stylesheet, and therefore not created or modified by the CCD consumer.
+ **/
+typedef struct {
+ /*< private >*/
+ ccd_background_t const *background;
+ ccd_border_stroke_t const *left;
+ ccd_border_stroke_t const *top;
+ ccd_border_stroke_t const *right;
+ ccd_border_stroke_t const *bottom;
+} ccd_style_t;
+
+void ccd_style_init (ccd_style_t *self);
+
+void ccd_style_draw_line (ccd_style_t const *self, cairo_t *cr,
+ int32_t x1, int32_t x2, int32_t y1, int32_t y2);
+
+void ccd_style_draw_outline (ccd_style_t const *self, cairo_t *cr,
+ int32_t x, int32_t y, int32_t width, int32_t height);
+
+void ccd_style_draw_rectangle (ccd_style_t const *self, cairo_t *cr,
+ int32_t x, int32_t y, int32_t width, int32_t height);
+
+void ccd_style_dump (ccd_style_t const *self);
+
+G_END_DECLS
+
+#endif /* CCD_STYLE_H */
+
Added: bzr-playground/libccd/ccd/ccd-stylesheet.c
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-stylesheet.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,444 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include "ccd-block.h"
+#include "ccd-node.h"
+#include "ccd-parser.h"
+#include "ccd-selector-group-priv.h"
+#include "ccd-selector.h"
+#include "ccd-stylesheet.h"
+
+/**
+ * ccd_stylesheet_t:
+ * @blocks: List owning all blocks parsed from the stylesheet.
+ * @type_rules: Associates type names with all applying selectors.
+ * @class_rules: Associates class names with all applying selectors.
+ * @id_rules: Associates IDs with all applying selectors.
+ *
+ * Represents a parsed instance of a stylesheet.
+ **/
+struct ccd_stylesheet_ {
+ GSList *blocks;
+ GHashTable *type_rules;
+ GHashTable *class_rules;
+ GHashTable *id_rules;
+};
+
+static ccd_stylesheet_t *
+ccd_stylesheet_new (void)
+{
+ ccd_stylesheet_t *self;
+
+ self = g_new0 (ccd_stylesheet_t, 1);
+ self->type_rules = g_hash_table_new (g_str_hash, g_str_equal);
+ self->class_rules = g_hash_table_new (g_str_hash, g_str_equal);
+ self->id_rules = g_hash_table_new (g_str_hash, g_str_equal);
+
+ return self;
+}
+
+static void
+fix_dangling_selectors (ccd_stylesheet_t *self)
+{
+ GHashTableIter iter;
+ char const *key;
+ char const *dangling_key;
+ ccd_selector_group_t *group;
+ ccd_selector_group_t *fixup_group;
+ GSList const *item;
+ bool have_dangling;
+ void *k;
+ void *v;
+
+ /* fix up dangling associations to base styles, walk the tree of type rules */
+ g_hash_table_iter_init (&iter, self->type_rules);
+ while (g_hash_table_iter_next (&iter, &k, &v)) {
+
+ /* walk extra mile to prevent warnings */
+ key = (char const *) k;
+ group = (ccd_selector_group_t *) v;
+
+ item = ccd_selector_group_get_dangling_selectors (group);
+ have_dangling = (bool) item;
+ /* walk the list of dangling selectors in the current group */
+ while (item) {
+ ccd_selector_t const *selector;
+ /* Merge fixup-group to satisfy dangling selectors.
+ * If no fixup_group is found that's ok too, the remaining dangling
+ * selectors will be removed in clear_dangling_selectors(). */
+ selector = (ccd_selector_t const *) item->data;
+ dangling_key = ccd_selector_get_key (selector);
+ fixup_group = g_hash_table_lookup (self->type_rules, dangling_key);
+ if (fixup_group) {
+ ccd_selector_group_merge_base (group, fixup_group);
+ }
+ item = item->next;
+ }
+ if (have_dangling) {
+ ccd_selector_group_clear_dangling_selectors (group);
+ }
+ }
+}
+
+/**
+ * ccd_stylesheet_new_from_buffer:
+ * @buffer: buffer to parse.
+ * @size: size of the buffer.
+ *
+ * Create a new stylesheet instance based on a CSS string.
+ *
+ * Returns: a #ccd_stylesheet_t representation of the CSS string.
+ **/
+ccd_stylesheet_t *
+ccd_stylesheet_new_from_buffer (char const *buffer,
+ size_t size)
+{
+ ccd_stylesheet_t *self;
+
+ g_critical ("%s() not tested", __FUNCTION__);
+
+ self = ccd_stylesheet_new ();
+
+ self->blocks = ccd_parser_parse_buffer (buffer, size, self->type_rules,
+ self->class_rules, self->id_rules);
+
+ fix_dangling_selectors (self);
+
+ return self;
+}
+
+/**
+ * ccd_stylesheet_new_from_file:
+ * @css_file: file to parse.
+ *
+ * Create a new stylesheet instance based on a CSS file.
+ *
+ * Returns: a #ccd_stylesheet_t representation of the CSS file.
+ **/
+ccd_stylesheet_t *
+ccd_stylesheet_new_from_file (char const *css_file)
+{
+ ccd_stylesheet_t *self;
+
+ self = ccd_stylesheet_new ();
+
+ self->blocks = ccd_parser_parse_file (css_file, self->type_rules,
+ self->class_rules, self->id_rules);
+
+ fix_dangling_selectors (self);
+
+ return self;
+}
+
+/**
+ * ccd_stylesheet_free:
+ * @self: a #ccd_stylesheet_t.
+ *
+ * Free the stylesheet and all associated resources.
+ **/
+void
+ccd_stylesheet_free (ccd_stylesheet_t *self)
+{
+ GSList *iter;
+ ccd_block_t *block;
+
+ g_assert (self);
+
+ iter = self->blocks;
+ while (iter) {
+ block = (ccd_block_t *) iter->data;
+ iter = g_slist_remove (iter, block);
+ ccd_block_free (block);
+ }
+
+ g_hash_table_destroy (self->type_rules);
+ g_hash_table_destroy (self->class_rules);
+ g_hash_table_destroy (self->id_rules);
+ g_free (self);
+}
+
+/**
+ * ccd_stylesheet_query_type:
+ * @self: a #ccd_stylesheet_t.
+ * @type_name: the type to query for, e.g. `h1'.
+ *
+ * Query the stylesheet for styling information regarding a type.
+ *
+ * Returns: a #ccd_selector_group_t containing the requested information of %NULL.
+ **/
+ccd_selector_group_t const *
+ccd_stylesheet_query_type (ccd_stylesheet_t const *self,
+ char const *type_name)
+{
+ ccd_selector_group_t const *group;
+
+ g_assert (self && type_name && self->type_rules);
+
+ group = (ccd_selector_group_t const *) g_hash_table_lookup (self->type_rules, type_name);
+
+ return group;
+}
+
+/*
+ * `base' is used for the recursion.
+ */
+static bool
+collect_type_r (ccd_stylesheet_t const *self,
+ ccd_node_t const *node,
+ ccd_node_t const *base,
+ ccd_selector_group_t *result_group,
+ bool as_base)
+{
+ ccd_node_class_t const *node_class;
+ ccd_selector_group_t *group;
+ char const *type_name;
+ bool ret;
+
+ node_class = ccd_node_get_class ();
+
+ type_name = node_class->get_type (base);
+
+ ret = false;
+ if (type_name) {
+
+ group = g_hash_table_lookup (self->type_rules, type_name);
+ if (group) {
+ ret = ccd_selector_group_query_collect (group, node, result_group, as_base);
+ }
+
+ /* Try to match base types. */
+ base = node_class->get_base_style (base);
+ if (base) {
+ ret |= collect_type_r (self, node, base, result_group, true);
+ node_class->release (base);
+ }
+
+ } else {
+ g_warning ("No type name");
+ }
+
+ return ret;
+}
+
+/**
+ * ccd_stylesheet_query_collect:
+ * @self: a #ccd_stylesheet_t.
+ * @node: a #ccd_node_t implementation that is used by libccd to retrieve information about the underlying document.
+ * @result_group: a #ccd_selector_group_t that accumulates the results of the query.
+ * @as_base: whether the results should be accumulates with lowered priority, e.g. when querying for base style information.
+ *
+ * Query the stylesheet for styling information regarding a document node and collect the results.
+ *
+ * Returns: %TRUE if styling information has been found.
+ **/
+bool
+ccd_stylesheet_query_collect (ccd_stylesheet_t const *self,
+ ccd_node_t const *node,
+ ccd_selector_group_t *result_group,
+ bool as_base)
+{
+ ccd_node_class_t const *node_class;
+ bool have_type;
+ bool have_class;
+ bool have_id;
+
+ node_class = ccd_node_get_class ();
+
+ g_return_val_if_fail (self && node && result_group, false);
+
+ /* match style by type information */
+ have_type = collect_type_r (self, node, node, result_group, as_base);
+
+ /* match by class name
+ have_class = match_class (self, node, style);
+ */
+ have_class = false;
+
+ /* match by id
+ have_id = query_id (self, node, style);
+ */
+ have_id = false;
+
+ return have_type || have_class || have_id;
+}
+
+/*
+ * `base' is used for the recursion.
+ */
+static bool
+apply_type_r (ccd_stylesheet_t const *self,
+ ccd_node_t const *node,
+ ccd_node_t const *base,
+ ccd_style_t *style)
+{
+ ccd_node_class_t const *node_class;
+ ccd_selector_group_t *group;
+ char const *type_name;
+ bool ret;
+
+ node_class = ccd_node_get_class ();
+
+ type_name = node_class->get_type (base);
+
+ ret = false;
+ if (type_name) {
+
+ group = g_hash_table_lookup (self->type_rules, type_name);
+ if (group) {
+ ret = ccd_selector_group_query_apply (group, node, style);
+ }
+
+ /* Try to match base types. */
+ base = node_class->get_base_style (base);
+ if (base) {
+ ret |= apply_type_r (self, node, base, style);
+ node_class->release (base);
+ }
+
+ } else {
+ g_warning ("No type name");
+ }
+
+ return ret;
+}
+
+/*
+ * Merge properties from global style classes.
+ * Note: not yet supported by libcroco.
+ */
+static bool
+match_class (ccd_stylesheet_t const *self,
+ ccd_node_t const *node,
+ ccd_style_t *style)
+{
+ ccd_node_class_t const *node_class;
+ ccd_selector_group_t *group;
+ char const *class_name;
+ bool ret;
+
+ node_class = ccd_node_get_class ();
+
+ ret = false;
+ class_name = node_class->get_class (node);
+ if (class_name) {
+ group = g_hash_table_lookup (self->class_rules, class_name);
+ if (group) {
+ ret |= ccd_selector_group_query_apply (group, node, style);
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Merge properties from global style classes.
+ * Note: not yet supported by libcroco.
+ */
+static bool
+match_id (ccd_stylesheet_t const *self,
+ ccd_node_t const *node,
+ ccd_style_t *style)
+{
+ ccd_node_class_t const *node_class;
+ ccd_selector_group_t *group;
+ char const *id;
+ bool ret;
+
+ node_class = ccd_node_get_class ();
+
+ ret = false;
+ id = node_class->get_id (node);
+ if (id) {
+ group = g_hash_table_lookup (self->id_rules, id);
+ if (group) {
+ ret |= ccd_selector_group_query_apply (group, node, style);
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * ccd_stylesheet_query_apply:
+ * @self: a #ccd_stylesheet_t.
+ * @node: a #ccd_node_t implementation that is used by libccd to retrieve information about the underlying document.
+ * @style: a #ccd_style_t that the results of the query are applied to.
+ *
+ * Query the stylesheet for styling information regarding a document node and apply the results to a #ccd_style_t object.
+ *
+ * Returns: %TRUE if styling information has been found.
+ **/
+bool
+ccd_stylesheet_query_apply (ccd_stylesheet_t const *self,
+ ccd_node_t const *node,
+ ccd_style_t *style)
+{
+ ccd_node_class_t const *node_class;
+ bool have_type;
+ bool have_class;
+ bool have_id;
+
+ node_class = ccd_node_get_class ();
+
+ g_return_val_if_fail (self && node && style, false);
+
+ /* match style by type information */
+ have_type = apply_type_r (self, node, node, style);
+
+ /* match by class name */
+ have_class = match_class (self, node, style);
+
+ /* match by id */
+ have_id = match_id (self, node, style);
+
+ return have_type || have_class || have_id;
+}
+
+/**
+ * ccd_stylesheet_dump:
+ * @self: a #ccd_stylesheet_t.
+ *
+ * Print informations about the internal state of this object.
+ **/
+void
+ccd_stylesheet_dump (ccd_stylesheet_t const *self)
+{
+ GHashTableIter iter;
+ char const *key;
+ ccd_selector_group_t *value;
+
+ g_return_if_fail (self && self->class_rules);
+
+ g_hash_table_iter_init (&iter, self->type_rules);
+ while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) {
+ ccd_selector_group_dump (value);
+ }
+
+ g_hash_table_iter_init (&iter, self->class_rules);
+ while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) {
+ ccd_selector_group_dump (value);
+ }
+
+ g_hash_table_iter_init (&iter, self->id_rules);
+ while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) {
+ ccd_selector_group_dump (value);
+ }
+}
+
Added: bzr-playground/libccd/ccd/ccd-stylesheet.h
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-stylesheet.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,52 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_STYLESHEET_H
+#define CCD_STYLESHEET_H
+
+#include <stdbool.h>
+#include <glib.h>
+#include <ccd/ccd-features.h>
+#include <ccd/ccd-selector-group.h>
+#include <ccd/ccd-style.h>
+
+G_BEGIN_DECLS
+
+typedef struct ccd_stylesheet_ ccd_stylesheet_t;
+
+ccd_stylesheet_t * ccd_stylesheet_new_from_buffer (char const *buffer,
+ size_t size);
+ccd_stylesheet_t * ccd_stylesheet_new_from_file (char const *css_file);
+void ccd_stylesheet_free (ccd_stylesheet_t *self);
+
+ccd_selector_group_t const * ccd_stylesheet_query_type (ccd_stylesheet_t const *self,
+ char const *type_name);
+
+bool ccd_stylesheet_query_collect (ccd_stylesheet_t const *self, ccd_node_t const *node,
+ ccd_selector_group_t *result_group, bool as_base);
+
+bool ccd_stylesheet_query_apply (ccd_stylesheet_t const *self, ccd_node_t const *node,
+ ccd_style_t *style);
+
+void ccd_stylesheet_dump (ccd_stylesheet_t const *self);
+
+G_END_DECLS
+
+#endif /* CCD_STYLESHEET_H */
+
Added: bzr-playground/libccd/ccd/ccd-utils.h
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd-utils.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,33 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_UTILS_H
+#define CCD_UTILS_H
+
+#include <glib.h>
+#include <ccd/ccd-features.h>
+
+G_BEGIN_DECLS
+
+#define CCD_PROPERTY_DUMP_PREFIX " "
+
+G_END_DECLS
+
+#endif /* CCD_UTILS_H */
+
Added: bzr-playground/libccd/ccd/ccd.c
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,46 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ccd.h"
+
+/**
+ * ccd_init:
+ * @node_class: dispatch table as described at #ccd_node_class_t.
+ *
+ * Initialize the CCD library before making any calls to it.
+ **/
+void
+ccd_init (ccd_node_class_t const *node_class)
+{
+ g_assert (node_class);
+
+ ccd_node_set_class (node_class);
+}
+
+/**
+ * ccd_shutdown:
+ *
+ * Shut down the CCD library.
+ **/
+void
+ccd_shutdown (void)
+{
+ ccd_node_reset_class ();
+}
+
Added: bzr-playground/libccd/ccd/ccd.h
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/ccd/ccd.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,47 @@
+/* The Cairo CSS Drawing Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CCD_H
+#define CCD_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#include <ccd/ccd-features.h>
+#include <ccd/ccd-node.h>
+#include <ccd/ccd-style.h>
+#include <ccd/ccd-stylesheet.h>
+
+#ifdef CCD_WITH_GTK
+#include <ccd/ccd-gtk-style.h>
+#endif /* CCD_WITH_GTK */
+
+#define XH(n_) (n_)
+#define YH(n_) (n_ + 0.5)
+#define XV(n_) (n_ + 0.5)
+#define YV(n_) (n_)
+
+void ccd_init (ccd_node_class_t const *node_class);
+void ccd_shutdown (void);
+
+G_END_DECLS
+
+#endif /* CCD_H */
+
Added: bzr-playground/libccd/doc/Makefile.am
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/doc/Makefile.am Mon Aug 18 13:50:33 2008
@@ -0,0 +1,52 @@
+## Process this file with automake to produce Makefile.in
+
+# The name of the module.
+DOC_MODULE=ccd
+
+# The top-level SGML file.
+DOC_MAIN_SGML_FILE=ccd-docs.sgml
+
+# The directory containing the source code. Relative to $(srcdir)
+DOC_SOURCE_DIR=../ccd
+
+# Extra options to pass to gtkdoc-scangobj
+SCANGOBJ_OPTIONS= --nogtkinit --type-init-func="ccd_init ()"
+
+# Extra options to supply to gtkdoc-scan
+SCAN_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkdb
+MKDB_OPTIONS=--sgml-mode --output-format=xml
+
+# Extra options to supply to gtkdoc-fixref
+FIXXREF_OPTIONS=
+
+# Used for dependencies
+HFILE_GLOB=$(top_srcdir)/libccd/ccd/*.h
+CFILE_GLOB=$(top_srcdir)/libccd/ccd/*.c
+
+# Header files to ignore when scanning
+IGNORE_HFILES =
+
+EXTRA_HFILES =
+
+# Images to copy into HTML directory
+HTML_IMAGES =
+
+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE)
+content_files =
+
+# Other files to distribute
+extra_files =
+
+# CFLAGS and LDFLAGS for compiling scan program. Only needed
+# if $(DOC_MODULE).types is non-empty.
+GTKDOC_CFLAGS = # -I$(top_srcdir) $(CCD_CFLAGS)
+GTKDOC_LIBS = # $(top_builddir)/libccd/ccd/libccd.la $(CCD_LIBS)
+
+if GTK_DOC_INSTALLED
+include $(top_srcdir)/gtk-doc.make
+CLEANFILES += ccd-scan.*
+.PHONY : dist-hook-local
+endif
+
Added: bzr-playground/libccd/doc/ccd-docs.sgml
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/doc/ccd-docs.sgml Mon Aug 18 13:50:33 2008
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+
+<!ENTITY ccd SYSTEM "xml/ccd.xml">
+<!ENTITY ccd_node_t SYSTEM "xml/node.xml">
+<!ENTITY ccd_style_t SYSTEM "xml/style.xml">
+<!ENTITY ccd_stylesheet_t SYSTEM "xml/stylesheet.xml">
+<!ENTITY ccd_selector_group_t SYSTEM "xml/selector_group.xml">
+
+<!ENTITY ccd_gtk_style_functions SYSTEM "xml/ccd_gtk_style_functions.xml">
+
+<!ENTITY TreeIndex SYSTEM "xml/tree_index.sgml">
+
+]>
+<book id="index">
+ <bookinfo>
+ <title>CCD Reference Manual</title>
+ </bookinfo>
+
+ <part id="intro">
+ <title>CCD: Introduction</title>
+ <partintro id="ccd-into">
+ <para>
+TODO
+ </para>
+ </partintro>
+ </part>
+
+ <part id="dependencies">
+ <title>CCD: Dependencies</title>
+ <para>
+CCD depends on the following libraries:
+<variablelist>
+
+<varlistentry>
+<term><link linkend="glib" title="GLib">GLib</link></term>
+<listitem><para>
+A general-purpose utility library, not specific to graphical user interfaces.
+GLib provides many useful data types, macros, type conversions,
+string utilities, file utilities, a main loop abstraction, and so on.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><link linkend="cairo" title="Cairo">Cairo</link></term>
+<listitem><para>
+Cairo is a 2D graphics library with support for multiple output devices.
+Currently supported output targets include the X Window System, Quartz, Win32,
+image buffers, PostScript, PDF, and SVG file output. Experimental backends
+include OpenGL (through glitz), XCB, BeOS, OS/2, and DirectFB.
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><link linkend="gtk+" title="Gtk+">Gtk+ (optional)</link></term>
+<listitem><para>
+GTK+ is a highly usable, feature rich toolkit for creating graphical user interfaces which boasts cross platform compatibility and an easy to use API. GTK+ it is written in C, but has bindings to many other popular programming languages such as C++, Python and C# among others. GTK+ is licensed under the GNU LGPL 2.1 allowing development of both free and proprietary software with GTK+ without any license fees or royalties.
+</para></listitem>
+</varlistentry>
+
+</variablelist>
+
+ </para>
+</part>
+
+<part id="ccd-users">
+ <title>Projects using CCD</title>
+ <partintro id="ccd-projects">
+ <para>
+CCD is used by
+<variablelist>
+<varlistentry>
+<term><ulink url="http://www.gnome.org/~robsta/gtk-css-engine/">Gtk CSS Engine</ulink></term>
+<listitem><para>
+The Gtk CSS Engine
+</para></listitem>
+</varlistentry>
+
+</variablelist>
+
+ </para>
+ </partintro>
+</part>
+
+<part id="api">
+ <title>API Reference</title>
+ <partintro id="ccd-api-ref">
+ <para>
+TODO.
+ </para>
+ </partintro>
+ <chapter id="basic">
+ <title>Basic Usage</title>
+ &ccd;
+ &ccd_stylesheet_t;
+ &ccd_selector_group_t;
+ &ccd_style_t;
+ &ccd_node_t;
+ </chapter>
+ <chapter id="gtk-support">
+ <title>Gtk+ Support</title>
+ &ccd_gtk_style_functions;
+ </chapter>
+ </part>
+<index id="ccd-index">
+&TreeIndex;
+</index>
+</book>
+
Added: bzr-playground/libccd/doc/ccd-sections.txt
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/doc/ccd-sections.txt Mon Aug 18 13:50:33 2008
@@ -0,0 +1,63 @@
+<SECTION>
+<SECTION>
+<TITLE>Initialization</TITLE>
+<FILE>ccd</FILE>
+ccd_init
+ccd_shutdown
+</SECTION>
+
+<TITLE>ccd_node_t</TITLE>
+<FILE>node</FILE>
+ccd_node_t
+ccd_node_class_t
+ccd_node_get_container_f
+ccd_node_get_base_style_f
+ccd_node_get_id_f
+ccd_node_get_type_f
+ccd_node_get_class_f
+ccd_node_get_pseudo_class_f
+ccd_node_get_attribute_f
+ccd_node_release_f
+</SECTION>
+
+<SECTION>
+<TITLE>ccd_style_t</TITLE>
+<FILE>style</FILE>
+ccd_style_t
+ccd_style_init
+ccd_style_draw_line
+ccd_style_draw_outline
+ccd_style_draw_rectangle
+ccd_style_dump
+</SECTION>
+
+<SECTION>
+<TITLE>ccd_stylesheet_t</TITLE>
+<FILE>stylesheet</FILE>
+ccd_stylesheet_t
+ccd_stylesheet_new_from_buffer
+ccd_stylesheet_new_from_file
+ccd_stylesheet_free
+ccd_stylesheet_query_type
+ccd_stylesheet_query_collect
+ccd_stylesheet_query_apply
+ccd_stylesheet_dump
+</SECTION>
+
+<SECTION>
+<TITLE>ccd_selector_group_t</TITLE>
+<FILE>selector_group</FILE>
+ccd_selector_group_t
+ccd_selector_group_new
+ccd_selector_group_free
+ccd_selector_group_apply
+ccd_selector_group_dump
+</SECTION>
+
+<SECTION>
+<TITLE>ccd_style_t Gtk+ Support</TITLE>
+<FILE>ccd_gtk_style_functions</FILE>
+ccd_style_draw_gap
+ccd_style_draw_polygon
+</SECTION>
+
Added: bzr-playground/libccd/doc/version.xml.in
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/doc/version.xml.in Mon Aug 18 13:50:33 2008
@@ -0,0 +1 @@
+ VERSION@
Added: bzr-playground/libccd/examples/Makefile.am
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/examples/Makefile.am Mon Aug 18 13:50:33 2008
@@ -0,0 +1,19 @@
+
+AM_CPPFLAGS = \
+ $(CCD_CFLAGS) \
+ -I$(top_srcdir)/libccd \
+ -I$(top_builddir)/libccd
+
+AM_LDFLAGS = \
+ $(CCD_LIBS) \
+ ../ccd/libccd.la
+
+noinst_PROGRAMS = example1 internal
+
+example1_SOURCES = example1.c
+
+internal_SOURCES = internal.c
+
+EXTRA_DIST = \
+ example1.css
+
Added: bzr-playground/libccd/examples/example1.c
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/examples/example1.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,70 @@
+
+#include <stdlib.h>
+#include <cairo.h>
+#include <ccd/ccd.h>
+#include <gtk/gtk.h>
+
+static gboolean
+expose_cb (GtkWidget *widget,
+ GdkEventExpose *event,
+ ccd_style_t const *style)
+{
+ cairo_t *cr;
+
+ cr = gdk_cairo_create (widget->window);
+
+ ccd_style_draw_rectangle (style, cr,
+ widget->allocation.x + 10,
+ widget->allocation.y + 10,
+ widget->allocation.width - 20,
+ widget->allocation.height - 20);
+
+ cairo_destroy (cr);
+
+ return FALSE;
+}
+
+/*
+static char const *_css = " \
+ box { \
+ border: 3px solid black \
+ } \
+";
+*/
+
+int
+main (int argc,
+ char **argv)
+{
+ ccd_stylesheet_t *stylesheet;
+ ccd_selector_group_t const *group;
+ ccd_style_t style;
+ GtkWidget *window;
+
+ gtk_init (&argc, &argv);
+
+ /* stylesheet = ccd_stylesheet_new_from_buffer (_css, sizeof (_css)); */
+ stylesheet = ccd_stylesheet_new_from_file ("example1.css");
+
+ group = ccd_stylesheet_query_type (stylesheet, "box");
+ g_assert (group);
+
+ ccd_style_init (&style);
+ ccd_selector_group_apply (group, &style);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_default_size (GTK_WINDOW (window), 160, 90);
+ gtk_widget_set_app_paintable (window, TRUE);
+ g_signal_connect (G_OBJECT (window), "delete-event",
+ G_CALLBACK (gtk_main_quit), NULL);
+ g_signal_connect (G_OBJECT (window), "expose-event",
+ G_CALLBACK (expose_cb), &style);
+
+ gtk_widget_show_all (window);
+ gtk_main ();
+
+ ccd_stylesheet_free (stylesheet);
+
+ return EXIT_SUCCESS;
+}
+
Added: bzr-playground/libccd/examples/example1.css
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/examples/example1.css Mon Aug 18 13:50:33 2008
@@ -0,0 +1,3 @@
+box {
+ border: 3px solid black
+}
Added: bzr-playground/libccd/examples/internal.c
==============================================================================
--- (empty file)
+++ bzr-playground/libccd/examples/internal.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,103 @@
+
+/*
+ * This example uses internal API.
+ */
+
+#include <gtk/gtk.h>
+#include <ccd/ccd.h>
+
+static void
+draw_decorations (GtkAllocation *allocation,
+ cairo_t *cr)
+{
+ cairo_move_to (cr, XV (30), YV (10));
+ cairo_line_to (cr, XV (30), YV (20));
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, XH (10), YH (30));
+ cairo_line_to (cr, XH (20), YH (30));
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, XV (allocation->width - 30), YV (10));
+ cairo_line_to (cr, XV (allocation->width - 30), YV (20));
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, XH (allocation->width - 20), YH (30));
+ cairo_line_to (cr, XH (allocation->width - 10), YH (30));
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, XH (allocation->width - 20), YH (allocation->height - 30));
+ cairo_line_to (cr, XH (allocation->width - 10), YH (allocation->height - 30));
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, XV (allocation->width - 30), YV (allocation->height - 20));
+ cairo_line_to (cr, XV (allocation->width - 30), YV (allocation->height - 10));
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, XV (30), YV (allocation->height - 20));
+ cairo_line_to (cr, XV (30), YV (allocation->height - 10));
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, XH (10), YH (allocation->height - 30));
+ cairo_line_to (cr, XH (20), YH (allocation->height - 30));
+ cairo_stroke (cr);
+}
+
+static void
+draw_box (cairo_t *cr,
+ double x,
+ double y,
+ double width,
+ double height)
+{
+ ccd_border_t border = {
+ .left.width = 3, .left.style = CCD_BORDER_STYLE_SOLID, .left.color.red = 0, .left.color.green = 0, .left.color.blue = 0,
+ .top.width = 10, .top.style = CCD_BORDER_STYLE_DOTTED, .top.color.red = 1, .top.color.green = 0, .top.color.blue = 0,
+ .right.width = 1, .right.style = CCD_BORDER_STYLE_DASHED, .right.color.red = 0, .right.color.green = 0, .right.color.blue = 0,
+ .bottom.width = 3, .bottom.style = CCD_BORDER_STYLE_SOLID, .bottom.color.red = 0, .bottom.color.green = 0, .bottom.color.blue = 0
+ };
+
+ ccd_border_draw (&border.left, &border.top, &border.right, &border.bottom, cr, x, y, width, height);
+}
+
+static gboolean
+expose_cb (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data)
+{
+ cairo_t *cr;
+
+ cr = gdk_cairo_create (widget->window);
+ cairo_set_line_width (cr, 1.0);
+
+ draw_decorations (&widget->allocation, cr);
+
+ draw_box (cr, 30, 30, widget->allocation.width - 60, widget->allocation.height - 60);
+
+ cairo_destroy (cr);
+
+ return FALSE;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GtkWidget *window;
+
+ gtk_init (&argc, &argv);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_widget_set_app_paintable (window, TRUE);
+ gtk_widget_set_size_request (window, 70, 70);
+ g_signal_connect (G_OBJECT (window), "expose-event",
+ G_CALLBACK (expose_cb), NULL);
+ g_signal_connect (G_OBJECT (window), "delete-event",
+ G_CALLBACK (gtk_main_quit), NULL);
+
+ gtk_widget_show_all (window);
+ gtk_main ();
+
+ return 0;
+}
+
Added: bzr-playground/src/Makefile.am
==============================================================================
--- (empty file)
+++ bzr-playground/src/Makefile.am Mon Aug 18 13:50:33 2008
@@ -0,0 +1,25 @@
+
+AM_CPPFLAGS = \
+ $(GCE_CFLAGS) \
+ -I$(top_srcdir)/libccd \
+ -I$(top_builddir)/libccd
+
+enginedir = $(libdir)/gtk-2.0/$(GTK_VERSION)/engines
+
+engine_LTLIBRARIES = libcss.la
+
+libcss_la_LDFLAGS = -module -avoid-version -no-undefined
+
+libcss_la_LIBADD = \
+ $(GCE_LIBS) \
+ ./../libccd/ccd/libccd.la
+
+libcss_la_SOURCES = \
+ gce-maps.c \
+ gce-maps.h \
+ gce-rc-style.c \
+ gce-rc-style.h \
+ gce-style.c \
+ gce-style.h \
+ gce-theme.c
+
Added: bzr-playground/src/gce-maps.c
==============================================================================
--- (empty file)
+++ bzr-playground/src/gce-maps.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,483 @@
+/* Gtk CSS Engine
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include "gce-maps.h"
+
+/**
+ * Map between detail strings in gtk and css format.
+ */
+static const struct {
+ char const *gtk_detail;
+ char const *css_detail;
+} _detail_map[] = {
+ { "add-mode", "add-mode" },
+ { "arrow", "arrow" },
+ { "bar", "bar" },
+ { "base", "base" },
+ { "button", "button" },
+ { "buttondefault", "buttondefault" },
+ { "calendar", "calendar" },
+ { "calendar-day", "calendar-day" },
+ { "cellcheck", "cellcheck" },
+ { "cell_even", "cell-even" },
+ { "cell_even_end", "cell-even-end" },
+ { "cell_even_middle", "cell-even-middle" },
+ { "cell_even_ruled", "cell-even-ruled" },
+ { "cell_even_ruled_end", "cell-even-ruled-end" },
+ { "cell_even_ruled_middle", "cell-even-ruled-middle" },
+ { "cell_even_ruled_sorted", "cell-even-ruled-sorted" },
+ { "cell_even_ruled_sorted_end", "cell-even-ruled-sorted-end" },
+ { "cell_even_ruled_sorted_middle", "cell-even-ruled-sorted-middle" },
+ { "cell_even_ruled_sorted_start", "cell-even-ruled-sorted-start" },
+ { "cell_even_ruled_start", "cell-even-ruled-start" },
+ { "cell_even_sorted", "cell-even-sorted" },
+ { "cell_even_sorted_end", "cell-even-sorted-end" },
+ { "cell_even_sorted_middle", "cell-even-sorted-middle" },
+ { "cell_even_sorted_start", "cell-even-sorted-start" },
+ { "cell_even_start", "cell-even-start" },
+ { "cell_odd", "cell-odd" },
+ { "cell_odd_end", "cell-odd-end" },
+ { "cell_odd_middle", "cell-odd-middle" },
+ { "cell_odd_ruled", "cell-odd-ruled" },
+ { "cell_odd_ruled_end", "cell-odd-ruled-end" },
+ { "cell_odd_ruled_middle", "cell-odd-ruled-middle" },
+ { "cell_odd_ruled_sorted", "cell-odd-ruled-sorted" },
+ { "cell_odd_ruled_sorted_end", "cell-odd-ruled-sorted-end" },
+ { "cell_odd_ruled_sorted_middle", "cell-odd-ruled-sorted-middle" },
+ { "cell_odd_ruled_sorted_start", "cell-odd-ruled-sorted-start" },
+ { "cell_odd_ruled_start", "cell-odd-ruled-start" },
+ { "cell_odd_sorted", "cell-odd-sorted" },
+ { "cell_odd_sorted_end", "cell-odd-sorted-end" },
+ { "cell_odd_sorted_middle", "cell-odd-sorted-middle" },
+ { "cell_odd_sorted_start", "cell-odd-sorted-start" },
+ { "cell_odd_start", "cell-odd-start" },
+ { "cellradio", "cellradio" },
+ { "check", "check" },
+ { "checkbutton", "checkbutton" },
+ { "colorwheel_dark", "colorwheel-dark" },
+ { "colorwheel_light", "colorwheel-light" },
+ { "combobox", "combobox" },
+ { "curve_bg", "curve-bg" },
+ { "dnd", "dnd" },
+ { "entry", "entry" },
+ { "entry_bg", "entry-bg" },
+ { "eventbox", "eventbox" },
+ { "expander", "expander" },
+ { "frame", "frame" },
+ { "handle", "handle" },
+ { "handlebox", "handlebox" },
+ { "handlebox_bin", "handlebox-bin" },
+ { "hruler", "hruler" },
+ { "hscale", "hscale" },
+ { "hscrollbar", "hscrollbar" },
+ { "hseparator", "hseparator" },
+ { "icon_view", "icon-view" },
+ { "iconview-drop-indicator", "iconview-drop-indicator" },
+ { "listitem", "listitem" },
+ { "menu", "menu" },
+ { "menubar", "menubar" },
+ { "menuitem", "menuitem" },
+ { "menu_scroll_arrow_down", "menu-scroll-arrow-down" },
+ { "menu_scroll_arrow_up", "menu-scroll-arrow-up" },
+ { "notebook", "notebook" },
+ { "option", "option" },
+ { "optionmenu", "optionmenu" },
+ { "optionmenutab", "optionmenutab" },
+ { "paned", "paned" },
+ { "radiobutton", "radiobutton" },
+ { "scrolled_window", "scrolled-window" },
+ { "spinbutton", "spinbutton" },
+ { "spinbutton_down", "spinbutton-down" },
+ { "spinbutton_up", "spinbutton-up" },
+ { "statusbar", "statusbar" },
+ { "tab", "tab" },
+ { "tearoffmenuitem", "tearoffmenuitem" },
+ { "text", "text" },
+ { "textview", "textview" },
+ { "through", "through" },
+ { "toolbar", "toolbar" },
+ { "tooltip", "tooltip" },
+ { "tray-icon", "tray-icon" },
+ { "treeitem", "treeitem" },
+ { "treeview", "treeview" },
+ { "treeview-drop-indicator", "treeview-drop-indicator" },
+ { "treeview-drop-indicator-left", "treeview-drop-indicator-left" },
+ { "treeview-drop-indicator-middle", "treeview-drop-indicator-middle" },
+ { "treeview-drop-indicator-right", "treeview-drop-indicator-right" },
+ { "treeview-left", "treeview-left" },
+ { "treeview-middle", "treeview-middle" },
+ { "treeview-right", "treeview-right" },
+ { "trough", "trough" },
+ { "trough-fill-level", "trough-fill-level" },
+ { "trough-fill-level-full", "trough-fill-level-full" },
+ { "trough-lower", "trough-lower" },
+ { "trough-upper", "trough-upper" },
+ { "viewport", "viewport" },
+ { "viewportbin", "viewportbin" },
+ { "vruler", "vruler" },
+ { "vscale", "vscale" },
+ { "vscrollbar", "vscrollbar" },
+ { "vseparator", "vseparator" }
+};
+
+/**
+ * Find gtk detail string for a given css detail.
+ *
+ * \note This could be sped up by manually comparing char by char. First
+ * traversing 'til the first one matches, then goin on with the second one ...
+ * If it would buy us anyting is another question.
+ */
+char const *
+gce_maps_match_detail (char const *css_detail)
+{
+ if (!css_detail) {
+ return NULL;
+ }
+
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_detail_map); i++) {
+ if (0 == strcmp (_detail_map[i].css_detail, css_detail)) {
+ return _detail_map[i].gtk_detail;
+ }
+ }
+
+ return NULL;
+}
+
+char const *
+gce_maps_get_detail (char const *gtk_detail)
+{
+ if (!gtk_detail) {
+ return NULL;
+ }
+
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_detail_map); i++) {
+ if (0 == strcmp (_detail_map[i].gtk_detail, gtk_detail)) {
+ return _detail_map[i].css_detail;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * Map between states in gtk and css format.
+ */
+static const struct {
+ GtkStateType gtk_state;
+ char const *css_state;
+} _state_map[] = {
+ { GTK_STATE_NORMAL, "normal" },
+ { GTK_STATE_ACTIVE, "active" },
+ { GTK_STATE_PRELIGHT, "prelight" },
+ { GTK_STATE_SELECTED, "selected" },
+ { GTK_STATE_INSENSITIVE, "insensitive" }
+};
+
+/**
+ * Default is GTK_STATE_NORMAL.
+ */
+GtkStateType
+gce_maps_match_state (char const *css_state)
+{
+ g_return_val_if_fail (css_state, GTK_STATE_NORMAL);
+
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_state_map); i++) {
+ if (0 == strcmp (_state_map[i].css_state, css_state)) {
+ return _state_map[i].gtk_state;
+ }
+ }
+
+ return GTK_STATE_NORMAL;
+}
+
+char const *
+gce_maps_get_state (GtkStateType gtk_state)
+{
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_state_map); i++) {
+ if (_state_map[i].gtk_state == gtk_state) {
+ return _state_map[i].css_state;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * Map between shadow types in gtk and css format.
+ */
+static const struct {
+ GtkShadowType gtk_shadow;
+ char const *css_shadow;
+} _shadow_map[] = {
+ { GTK_SHADOW_NONE, "none" },
+ { GTK_SHADOW_IN, "in" },
+ { GTK_SHADOW_OUT, "out" },
+ { GTK_SHADOW_ETCHED_IN, "etched-in" },
+ { GTK_SHADOW_ETCHED_OUT, "etched-out" }
+};
+
+/**
+ * Default is GTK_SHADOW_NONE.
+ */
+GtkShadowType
+gce_maps_match_shadow (char const *css_shadow)
+{
+ g_return_val_if_fail (css_shadow, GTK_SHADOW_NONE);
+
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_shadow_map); i++) {
+ if (0 == strcmp (_shadow_map[i].css_shadow, css_shadow)) {
+ return _shadow_map[i].gtk_shadow;
+ }
+ }
+
+ return GTK_SHADOW_NONE;
+}
+
+char const *
+gce_maps_get_shadow (GtkShadowType gtk_shadow)
+{
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_shadow_map); i++) {
+ if (_shadow_map[i].gtk_shadow == gtk_shadow) {
+ return _shadow_map[i].css_shadow;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * Map between arrow types in gtk and css format.
+ */
+static const struct {
+ GtkArrowType gtk_arrow;
+ char const *css_arrow;
+} _arrow_map[] = {
+ { GTK_ARROW_UP, "up" },
+ { GTK_ARROW_DOWN, "down" },
+ { GTK_ARROW_LEFT, "left" },
+ { GTK_ARROW_RIGHT, "right" },
+ { GTK_ARROW_NONE, "none" }
+};
+
+/**
+ * Default is GTK_ARROW_NONE.
+ */
+GtkArrowType
+gce_maps_match_arrow (char const *css_arrow)
+{
+ g_return_val_if_fail (css_arrow, GTK_ARROW_NONE);
+
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_arrow_map); i++) {
+ if (0 == strcmp (_arrow_map[i].css_arrow, css_arrow)) {
+ return _arrow_map[i].gtk_arrow;
+ }
+ }
+
+ return GTK_ARROW_NONE;
+}
+
+char const *
+gce_maps_get_arrow (GtkArrowType gtk_arrow)
+{
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_arrow_map); i++) {
+ if (_arrow_map[i].gtk_arrow == gtk_arrow) {
+ return _arrow_map[i].css_arrow;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * Map between position types in gtk and css format.
+ */
+static const struct {
+ GtkPositionType gtk_position;
+ char const *css_position;
+} _position_map[] = {
+ { GTK_POS_LEFT, "left" },
+ { GTK_POS_RIGHT, "right" },
+ { GTK_POS_TOP, "top" },
+ { GTK_POS_BOTTOM, "bottom" },
+};
+
+/**
+ * Default is GTK_POS_LEFT.
+ */
+GtkPositionType
+gce_maps_match_position (char const *css_position)
+{
+ g_return_val_if_fail (css_position, GTK_POS_LEFT);
+
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_position_map); i++) {
+ if (0 == strcmp (_position_map[i].css_position, css_position)) {
+ return _position_map[i].gtk_position;
+ }
+ }
+
+ return GTK_POS_LEFT;
+}
+
+char const *
+gce_maps_get_position (GtkPositionType gtk_position)
+{
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_position_map); i++) {
+ if (_position_map[i].gtk_position == gtk_position) {
+ return _position_map[i].css_position;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * Map between edge types in gdk and css format.
+ */
+static const struct {
+ GdkWindowEdge gdk_window_edge;
+ char const *css_window_edge;
+} _window_edge_map[] = {
+ { GDK_WINDOW_EDGE_NORTH_WEST, "north-west" },
+ { GDK_WINDOW_EDGE_NORTH, "north" },
+ { GDK_WINDOW_EDGE_NORTH_EAST, "north-east" },
+ { GDK_WINDOW_EDGE_WEST, "west" },
+ { GDK_WINDOW_EDGE_EAST, "east" },
+ { GDK_WINDOW_EDGE_SOUTH_WEST, "south-west" },
+ { GDK_WINDOW_EDGE_SOUTH, "south" },
+ { GDK_WINDOW_EDGE_SOUTH_EAST, "south-east" },
+};
+
+/**
+ * Default is GDK_WINDOW_EDGE_SOUTH_EAST.
+ */
+GdkWindowEdge
+gce_maps_match_window_edge (char const *css_window_edge)
+{
+ g_return_val_if_fail (css_window_edge, GDK_WINDOW_EDGE_SOUTH_EAST);
+
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_window_edge_map); i++) {
+ if (0 == strcmp (_window_edge_map[i].css_window_edge, css_window_edge)) {
+ return _window_edge_map[i].gdk_window_edge;
+ }
+ }
+
+ return GDK_WINDOW_EDGE_SOUTH_EAST;
+}
+
+char const *
+gce_maps_get_window_edge (GdkWindowEdge gdk_window_edge)
+{
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_window_edge_map); i++) {
+ if (_window_edge_map[i].gdk_window_edge == gdk_window_edge) {
+ return _window_edge_map[i].css_window_edge;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * Map between orientation types in gtk and css format.
+ */
+static const struct {
+ GtkOrientation gtk_orientation;
+ char const *css_orientation;
+} _orientation_map[] = {
+ { GTK_ORIENTATION_HORIZONTAL, "horizontal" },
+ { GTK_ORIENTATION_VERTICAL, "vertical" }
+};
+
+/**
+ * Default is GTK_ORIENTATION_HORIZONTAL.
+ */
+GtkOrientation
+gce_maps_match_orientation (char const *css_orientation)
+{
+ g_return_val_if_fail (css_orientation, GTK_ORIENTATION_HORIZONTAL);
+
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_orientation_map); i++) {
+ if (0 == strcmp (_orientation_map[i].css_orientation, css_orientation)) {
+ return _orientation_map[i].gtk_orientation;
+ }
+ }
+
+ return GTK_ORIENTATION_HORIZONTAL;
+}
+
+char const *
+gce_maps_get_orientation (GtkOrientation gtk_orientation)
+{
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_orientation_map); i++) {
+ if (_orientation_map[i].gtk_orientation == gtk_orientation) {
+ return _orientation_map[i].css_orientation;
+ }
+ }
+
+ return NULL;
+}
+
+
+
+
+
+
+
+/**
+ * Map between expander style types in gtk and css format.
+ */
+static const struct {
+ GtkExpanderStyle gtk_expander_style;
+ char const *css_expander_style;
+} _expander_style_map[] = {
+ { GTK_EXPANDER_COLLAPSED, "collapsed" },
+ { GTK_EXPANDER_SEMI_COLLAPSED, "semi-collapsed" },
+ { GTK_EXPANDER_SEMI_EXPANDED, "semi-expanded" },
+ { GTK_EXPANDER_EXPANDED, "expanded" }
+};
+
+/**
+ * Default is GTK_EXPANDER_COLLAPSED.
+ */
+GtkExpanderStyle
+gce_maps_match_expander_style (char const *css_expander_style)
+{
+ g_return_val_if_fail (css_expander_style, GTK_EXPANDER_COLLAPSED);
+
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_expander_style_map); i++) {
+ if (0 == strcmp (_expander_style_map[i].css_expander_style, css_expander_style)) {
+ return _expander_style_map[i].gtk_expander_style;
+ }
+ }
+
+ return GTK_EXPANDER_COLLAPSED;
+}
+
+char const *
+gce_maps_get_expander_style (GtkExpanderStyle gtk_expander_style)
+{
+ for (unsigned int i = 0; i < G_N_ELEMENTS (_expander_style_map); i++) {
+ if (_expander_style_map[i].gtk_expander_style == gtk_expander_style) {
+ return _expander_style_map[i].css_expander_style;
+ }
+ }
+
+ return NULL;
+}
+
Added: bzr-playground/src/gce-maps.h
==============================================================================
--- (empty file)
+++ bzr-playground/src/gce-maps.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,55 @@
+/* Gtk CSS Engine
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GCE_MAPS_H
+#define GCE_MAPS_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+char const * gce_maps_match_detail (char const *gce_detail);
+char const * gce_maps_get_detail (char const *gtk_detail);
+
+GtkStateType gce_maps_match_state (char const *gce_state);
+char const * gce_maps_get_state (GtkStateType state);
+
+GtkShadowType gce_maps_match_shadow (char const *gce_shadow);
+char const * gce_maps_get_shadow (GtkShadowType shadow);
+
+GtkArrowType gce_maps_match_arrow (char const *gce_arrow);
+char const * gce_maps_get_arrow (GtkArrowType gtk_arrow);
+
+GtkPositionType gce_maps_match_position (char const *gce_position);
+char const * gce_maps_get_position (GtkPositionType gtk_position);
+
+GdkWindowEdge gce_maps_match_window_edge (char const *gce_window_edge);
+char const * gce_maps_get_window_edge (GdkWindowEdge gdk_window_edge);
+
+GtkOrientation gce_maps_match_orientation (char const *css_orientation);
+char const * gce_maps_get_orientation (GtkOrientation gtk_orientation);
+
+GtkExpanderStyle gce_maps_match_expander_style (char const *css_expander_style);
+char const * gce_maps_get_expander_style (GtkExpanderStyle gtk_expander_style);
+
+G_END_DECLS
+
+#endif /* GCE_MAPS_H */
+
Added: bzr-playground/src/gce-rc-style.c
==============================================================================
--- (empty file)
+++ bzr-playground/src/gce-rc-style.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,169 @@
+/* Gtk CSS Engine
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtk.h>
+#include <string.h>
+#include "gce-rc-style.h"
+#include "gce-style.h"
+
+static ccd_stylesheet_t *_stylesheet = NULL;
+gpointer *_stylesheet_owner = NULL;
+
+ccd_stylesheet_t const *
+gce_rc_style_get_stylesheet (void)
+{
+ return _stylesheet;
+}
+
+struct _GceRcStyle
+{
+ GtkRcStyle parent;
+};
+
+struct _GceRcStyleClass
+{
+ GtkRcStyleClass parent;
+};
+
+static GType gce_rc_style_type = 0;
+static GtkRcStyleClass *gce_rc_style_parent_class = NULL;
+
+static GtkStyle*
+create_style (GtkRcStyle *rc_style)
+{
+ return GTK_STYLE (g_object_new (GCE_TYPE_STYLE, NULL));
+}
+
+static guint
+parse (GtkRcStyle *rc_style,
+ GtkSettings *settings,
+ GScanner *scanner)
+{
+ static GQuark scope_id = 0;
+
+ char *gce_file;
+ guint old_scope;
+ guint token;
+
+ if (!scope_id)
+ scope_id = g_quark_from_string ("gce_engine");
+
+ old_scope = g_scanner_set_scope (scanner, scope_id);
+
+ token = g_scanner_peek_next_token (scanner);
+ if (token != G_TOKEN_RIGHT_CURLY) {
+
+ token = g_scanner_get_next_token (scanner);
+ g_assert (token == G_TOKEN_IDENTIFIER &&
+ 0 == strcmp ("href", scanner->value.v_identifier));
+
+ token = g_scanner_get_next_token (scanner);
+ g_assert (token == '=');
+
+ token = g_scanner_get_next_token (scanner);
+ g_assert (token == G_TOKEN_STRING);
+ g_assert (_stylesheet == NULL);
+ gce_file = gtk_rc_find_pixmap_in_path (gtk_settings_get_default (),
+ scanner, scanner->value.v_string);
+ _stylesheet = ccd_stylesheet_new_from_file (gce_file);
+#ifdef DEBUG
+ ccd_stylesheet_dump (_stylesheet);
+#endif
+ _stylesheet_owner = (gpointer) rc_style;
+ g_free (gce_file), gce_file = NULL;
+ }
+
+ g_scanner_get_next_token (scanner);
+ g_scanner_set_scope (scanner, old_scope);
+
+ return G_TOKEN_NONE;
+}
+
+static void
+merge (GtkRcStyle *dst,
+ GtkRcStyle *src)
+{
+ gce_rc_style_parent_class->merge (dst, src);
+}
+
+static void
+finalize (GObject *instance)
+{
+ /*
+ GceRcStyle *self;
+ self = GCE_RC_STYLE (instance);
+ */
+
+ if (_stylesheet_owner == (gpointer) instance) {
+ ccd_stylesheet_free (_stylesheet);
+ }
+
+ G_OBJECT_CLASS (gce_rc_style_parent_class)->finalize (instance);
+}
+
+static void
+instance_init (GceRcStyle *self)
+{
+}
+
+static void
+class_init (GceRcStyleClass *klass)
+{
+ GObjectClass *go_class;
+ GtkRcStyleClass *rc_style_class;
+
+ gce_rc_style_parent_class = g_type_class_peek_parent (klass);
+
+ go_class = G_OBJECT_CLASS (klass);
+ go_class->finalize = finalize;
+
+ rc_style_class = GTK_RC_STYLE_CLASS (klass);
+ rc_style_class->create_style = create_style;
+ rc_style_class->parse = parse;
+ rc_style_class->merge = merge;
+}
+
+void
+gce_rc_style_register_type (GTypeModule *module)
+{
+ if (!gce_rc_style_type) {
+ static const GTypeInfo info = {
+ sizeof(GceRcStyleClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GceRcStyle),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) instance_init,
+ };
+
+ gce_rc_style_type = g_type_module_register_type (module,
+ GTK_TYPE_RC_STYLE,
+ "GceRcStyle",
+ &info, 0);
+ }
+}
+
+GType
+gce_rc_style_get_type (void)
+{
+ return gce_rc_style_type;
+}
Added: bzr-playground/src/gce-rc-style.h
==============================================================================
--- (empty file)
+++ bzr-playground/src/gce-rc-style.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,46 @@
+/* Gtk CSS Engine
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GCE_RC_STYLE_H
+#define GCE_RC_STYLE_H
+
+#include <ccd/ccd.h>
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GCE_TYPE_RC_STYLE (gce_rc_style_get_type ())
+#define GCE_RC_STYLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GCE_TYPE_RC_STYLE, GceRcStyle))
+#define GCE_RC_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCE_TYPE_RC_STYLE, GceRcStyleClass))
+#define GCE_IS_RC_STYLE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GCE_TYPE_RC_STYLE))
+#define GCE_IS_RC_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCE_TYPE_RC_STYLE))
+#define GCE_RC_STYLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCE_TYPE_RC_STYLE, GceRcStyleClass))
+
+typedef struct _GceRcStyle GceRcStyle;
+typedef struct _GceRcStyleClass GceRcStyleClass;
+
+void gce_rc_style_register_type (GTypeModule *module);
+GType gce_rc_style_get_type (void) G_GNUC_CONST;
+
+ccd_stylesheet_t const * gce_rc_style_get_stylesheet (void);
+
+G_END_DECLS
+
+#endif /* GCE_RC_STYLE_H */
Added: bzr-playground/src/gce-style.c
==============================================================================
--- (empty file)
+++ bzr-playground/src/gce-style.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,1269 @@
+/* Gtk CSS Engine
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include "gce-rc-style.h"
+#include "gce-style.h"
+#include "gce-maps.h"
+
+/* Implementation of hooks for the ccd library */
+
+enum GceNodeAttributeFlags {
+ CLASS = 1 << 0,
+ PSEUDO_CLASS = 1 << 1,
+ SHADOW = 1 << 2
+};
+
+/*
+ * TODO: split into load- and run-time variants?
+ */
+typedef struct GceNode_ {
+ ccd_node_t parent;
+ GtkWidget *widget;
+ /* custom attributes { */
+ char const *class_name;
+ char const *pseudo_class;
+ char const *shadow;
+ char const *orientation;
+ char const *edge;
+ char const *expander_style;
+ /* } */
+ enum {
+ UNSET,
+ CONTAINER,
+ PRIMITIVE,
+ TYPE
+ } flavor;
+ union {
+ char const *primitive;
+ GType gtype;
+ } impl;
+} GceNode;
+
+#define NODE_CACHE_SIZE 24
+
+static struct GceNodeCache {
+ GceNode nodes[NODE_CACHE_SIZE];
+ int cursor;
+} _node_cache = {
+ .cursor = -1
+};
+
+static GceNode *
+node_cache_top (struct GceNodeCache *cache)
+{
+ g_assert (cache);
+
+ return &cache->nodes[cache->cursor];
+}
+
+static GceNode *
+node_cache_push (struct GceNodeCache *cache)
+{
+ GceNode *node;
+
+ g_assert (cache && cache->cursor < (NODE_CACHE_SIZE - 1));
+
+ cache->cursor++;
+ node = &cache->nodes[cache->cursor];
+ memset (node, 0, sizeof (*node));
+
+ return node;
+}
+
+static void
+node_cache_pop (struct GceNodeCache *cache)
+{
+ g_assert (cache && cache->cursor >= 0);
+
+ cache->cursor--;
+}
+
+static gboolean
+is_a (GceNode const *node,
+ char const *type_name)
+{
+ GType gtype;
+
+ switch (node->flavor) {
+ case PRIMITIVE:
+ if (0 == strcmp (type_name, node->impl.primitive)) {
+ return TRUE;
+ }
+ /* fall thru */
+ case UNSET:
+ case CONTAINER:
+ case TYPE:
+ gtype = g_type_from_name (type_name);
+ return g_type_is_a (G_OBJECT_TYPE (node->widget), gtype);
+ default:
+ g_assert_not_reached ();
+ return FALSE;
+ }
+}
+
+static GceNode *
+get_container (GceNode const *node)
+{
+ GceNode *container_node;
+ GtkWidget *container;
+
+ g_assert (node);
+
+ switch (node->flavor) {
+ case UNSET:
+ case CONTAINER:
+ container = gtk_widget_get_parent (node->widget);
+ if (container) {
+ container_node = node_cache_push (&_node_cache);
+ container_node->flavor = CONTAINER;
+ container_node->widget = (GtkWidget *) g_object_ref (G_OBJECT (container));
+ container_node->impl.gtype = G_OBJECT_TYPE (G_OBJECT (container));
+ }
+ break;
+ case PRIMITIVE:
+ container_node = node_cache_push (&_node_cache);
+ container_node->flavor = UNSET;
+ container_node->widget = (GtkWidget *) g_object_ref (G_OBJECT (node->widget));
+ container_node->impl.primitive = NULL;
+ break;
+ case TYPE:
+ g_assert_not_reached ();
+ /* fall thru */
+ default:
+ container_node = NULL;
+ }
+
+ return container_node;
+}
+
+static GceNode *
+get_base_style (GceNode const *node)
+{
+ GceNode *base_node;
+
+ g_assert (node);
+
+ switch (node->flavor) {
+ case UNSET:
+ if (GTK_TYPE_WIDGET == G_OBJECT_TYPE (G_OBJECT (node->widget))) {
+ /* already at top of inheritance hierarchy */
+ base_node = NULL;
+ } else {
+ /* inherit from superclass widget */
+ base_node = node_cache_push (&_node_cache);
+ base_node->widget = (GtkWidget *) g_object_ref (node->widget);
+ base_node->flavor = TYPE;
+ base_node->impl.gtype = g_type_parent (G_OBJECT_TYPE (G_OBJECT (node->widget)));
+ }
+ break;
+ case CONTAINER:
+ if (GTK_TYPE_WIDGET == node->impl.gtype) {
+ /* already at top of inheritance hierarchy */
+ base_node = NULL;
+ } else {
+ /* inherit from superclass widget */
+ base_node = node_cache_push (&_node_cache);
+ base_node->widget = (GtkWidget *) g_object_ref (node->widget);
+ base_node->flavor = CONTAINER;
+ base_node->impl.gtype = g_type_parent (node->impl.gtype);
+ }
+ break;
+ case PRIMITIVE:
+ base_node = NULL;
+ break;
+ case TYPE:
+ if (GTK_TYPE_WIDGET == node->impl.gtype) {
+ /* already at top of inheritance hierarchy */
+ base_node = NULL;
+ } else {
+ /* inherit from superclass widget */
+ base_node = node_cache_push (&_node_cache);
+ base_node->widget = (GtkWidget *) g_object_ref (node->widget);
+ base_node->flavor = TYPE;
+ base_node->impl.gtype = g_type_parent (node->impl.gtype);
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ base_node = NULL;
+ }
+
+ return base_node;
+}
+
+static char const *
+get_id (GceNode const *node)
+{
+ g_return_val_if_fail (node, NULL);
+
+ switch (node->flavor) {
+ case UNSET:
+ case CONTAINER:
+ case PRIMITIVE:
+ return gtk_widget_get_name (node->widget);
+ case TYPE:
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
+}
+
+static char const *
+get_type (GceNode const *node)
+{
+ g_return_val_if_fail (node, NULL);
+
+ switch (node->flavor) {
+ case UNSET:
+ return G_OBJECT_TYPE_NAME (G_OBJECT (node->widget));
+ case CONTAINER:
+ case TYPE:
+ return g_type_name (node->impl.gtype);
+ case PRIMITIVE:
+ g_assert (node->impl.primitive);
+ return node->impl.primitive;
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
+}
+
+static char const *
+get_class (GceNode const *node)
+{
+ g_return_val_if_fail (node, NULL);
+
+ return node->class_name;
+}
+
+static char const *
+get_pseudo_class (GceNode const *node)
+{
+ g_return_val_if_fail (node, NULL);
+
+ return node->pseudo_class;
+}
+
+static char const *
+get_attribute (GceNode const *node,
+ char const *name)
+{
+ GValue property;
+ char const *value;
+
+ g_assert (node && node->widget);
+
+ if (node->flavor == TYPE) {
+ g_warning ("Querying attribute `%s' on something not a widget", name);
+ return NULL;
+ }
+
+ /* attributes provided in the drawing function take precedence */
+ if (0 == strcmp ("shadow", name)) {
+ return node->shadow;
+ } else if (0 == strcmp ("orientation", name)) {
+ return node->orientation;
+ } else if (0 == strcmp ("edge", name)) {
+ return node->edge;
+ } else if (0 == strcmp ("expander-style", name)) {
+ return node->expander_style;
+ }
+
+ /* now try to find an apropriate style property */
+ g_value_unset (&property);
+ gtk_widget_style_get_property (node->widget, name, &property);
+ value = NULL;
+ if (G_VALUE_HOLDS (&property, G_TYPE_BOOLEAN)) {
+ value = g_value_get_boolean (&property) ? "true" : "false";
+ } else if (G_VALUE_HOLDS (&property, G_TYPE_STRING)) {
+ value = g_value_get_string (&property);
+ } else {
+ g_warning ("Querying for properties of type `%s' is not supported yet.",
+ G_VALUE_TYPE_NAME (&property));
+ }
+
+ return value;
+}
+
+static void
+release (GceNode *node)
+{
+ g_assert (node == node_cache_top (&_node_cache));
+
+ if (node->widget) {
+ g_object_unref (G_OBJECT (node->widget));
+ }
+
+ node_cache_pop (&_node_cache);
+}
+
+static const ccd_node_class_t _node_class = {
+ .is_a = (ccd_node_is_a_f) is_a,
+ .get_container = (ccd_node_get_container_f) get_container,
+ .get_base_style = (ccd_node_get_base_style_f) get_base_style,
+ .get_id = (ccd_node_get_id_f) get_id,
+ .get_type = (ccd_node_get_type_f) get_type,
+ .get_class = (ccd_node_get_class_f) get_class,
+ .get_pseudo_class = (ccd_node_get_pseudo_class_f) get_pseudo_class,
+ .get_attribute = (ccd_node_get_attribute_f) get_attribute,
+ .release = (ccd_node_release_f) release
+};
+
+ccd_node_class_t const *
+gce_style_get_ccd_node_class (void)
+{
+ return &_node_class;
+}
+
+/* Implementation of the engine's GtkStyle subclass */
+
+struct _GceStyle
+{
+ GtkStyle parent;
+};
+
+struct _GceStyleClass
+{
+ GtkStyleClass parent;
+};
+
+
+static GType gce_style_type = 0;
+static GtkStyleClass *gce_style_parent_class = NULL;
+
+static ccd_selector_group_t *
+setup (GceNode const *node,
+ GceNode const *base)
+{
+ ccd_stylesheet_t const *stylesheet;
+ ccd_selector_group_t *group;
+ gboolean status;
+
+ stylesheet = gce_rc_style_get_stylesheet ();
+ group = ccd_selector_group_new ();
+ status = FALSE;
+
+ /* query for widget theming */
+ status |= ccd_stylesheet_query_collect (stylesheet, (ccd_node_t const *) node, group, FALSE);
+
+ /* query for primitive theming */
+ status |= ccd_stylesheet_query_collect (stylesheet, (ccd_node_t const *) base, group, TRUE);
+
+ if (!status) {
+ g_warning ("Un-themed widget `%s', primitive `%s'.",
+ G_OBJECT_TYPE_NAME (G_OBJECT (node->widget)), base->impl.primitive);
+ ccd_selector_group_free (group);
+ group = NULL;
+ }
+
+ return group;
+}
+
+static void
+rectangle (GtkStyle *self,
+ GceNode const *node,
+ GceNode const *base,
+ GdkWindow *window,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ gboolean fill)
+{
+ ccd_selector_group_t *group;
+ ccd_style_t style;
+ cairo_t *cr;
+
+ group = setup (node, base);
+ if (group) {
+ cr = gdk_cairo_create (window);
+ ccd_style_init (&style);
+
+ if (area) {
+ gdk_cairo_rectangle (cr, area);
+ cairo_clip (cr);
+ }
+
+ ccd_selector_group_apply (group, &style);
+ if (fill) {
+ ccd_style_draw_rectangle (&style, cr, x, y, width, height);
+ } else {
+ ccd_style_draw_outline (&style, cr, x, y, width, height);
+ }
+
+ cairo_destroy (cr);
+ ccd_selector_group_free (group);
+ }
+}
+
+static void
+gap (GtkStyle *self,
+ GceNode const *node,
+ GceNode const *base,
+ GdkWindow *window,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ GtkPositionType gap_side,
+ gint gap_start,
+ gint gap_width)
+{
+ ccd_selector_group_t *group;
+ ccd_style_t style;
+ cairo_t *cr;
+
+ group = setup (node, base);
+ if (group) {
+ cr = gdk_cairo_create (window);
+ ccd_style_init (&style);
+
+ if (area) {
+ gdk_cairo_rectangle (cr, area);
+ cairo_clip (cr);
+ }
+
+ ccd_selector_group_apply (group, &style);
+ ccd_style_draw_gap (&style, cr, x, y, width, height, gap_side, gap_start, gap_width);
+
+ cairo_destroy (cr);
+ ccd_selector_group_free (group);
+ }
+}
+
+static void
+line (GtkStyle *self,
+ GceNode *node,
+ GceNode *base,
+ GdkWindow *window,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ gint x1,
+ gint x2,
+ gint y1,
+ gint y2)
+{
+ ccd_selector_group_t *group;
+ ccd_style_t style;
+ cairo_t *cr;
+
+ group = setup (node, base);
+ if (group) {
+ cr = gdk_cairo_create (window);
+ ccd_style_init (&style);
+
+ if (area) {
+ gdk_cairo_rectangle (cr, area);
+ cairo_clip (cr);
+ }
+
+ ccd_selector_group_apply (group, &style);
+ ccd_style_draw_line (&style, cr, x1, x2, y1, y2);
+
+ cairo_destroy (cr);
+ ccd_selector_group_free (group);
+ }
+}
+
+static void
+draw_hline (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ gint x1,
+ gint x2,
+ gint y)
+{
+ GceNode *node;
+ GceNode *base;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "hline";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->flavor = UNSET;
+
+ line (self, node, base, window, area, widget, x1, x2, y, y);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+}
+
+static void
+draw_vline (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ gint y1,
+ gint y2,
+ gint x)
+{
+ GceNode *node;
+ GceNode *base;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "vline";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->flavor = UNSET;
+
+ line (self, node, base, window, area, widget, x, x, y1, y2);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+
+}
+
+static void
+draw_shadow (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GtkShadowType shadow,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GceNode *node;
+ GceNode *base;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->shadow = gce_maps_get_shadow (shadow);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "shadow";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->shadow = base->shadow;
+ node->flavor = UNSET;
+
+ rectangle (self, node, base, window, area, widget,
+ x, y, width, height, TRUE);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+}
+
+static void
+draw_box (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GtkShadowType shadow,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GceNode *node;
+ GceNode *base;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->shadow = gce_maps_get_shadow (shadow);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "box";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->shadow = base->shadow;
+ node->flavor = UNSET;
+
+ rectangle (self, node, base, window, area, widget,
+ x, y, width, height, TRUE);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+}
+
+static void
+draw_flat_box (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GtkShadowType shadow,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GceNode *node;
+ GceNode *base;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->shadow = gce_maps_get_shadow (shadow);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "flatbox";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->shadow = base->shadow;
+ node->flavor = UNSET;
+
+ rectangle (self, node, base, window, area, widget,
+ x, y, width, height, TRUE);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+}
+
+static void
+draw_check (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GtkShadowType shadow,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GceNode *node;
+ GceNode *base;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->shadow = gce_maps_get_shadow (shadow);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "check";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->shadow = base->shadow;
+ node->flavor = UNSET;
+
+ rectangle (self, node, base, window, area, widget,
+ x, y, width, height, TRUE);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+}
+
+static void
+draw_option (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GtkShadowType shadow,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GceNode *node;
+ GceNode *base;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->shadow = gce_maps_get_shadow (shadow);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "option";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->shadow = base->shadow;
+ node->flavor = UNSET;
+
+ rectangle (self, node, base, window, area, widget,
+ x, y, width, height, TRUE);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+}
+
+static void
+draw_shadow_gap (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GtkShadowType shadow,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ GtkPositionType gap_side,
+ gint gap_start,
+ gint gap_width)
+{
+ GceNode *node;
+ GceNode *base;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->shadow = gce_maps_get_shadow (shadow);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "shadow";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->shadow = base->shadow;
+ node->flavor = UNSET;
+
+ gap (self, node, base, window, area, widget,
+ x, y, width, height, gap_side, gap_start, gap_width);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+}
+
+static void
+draw_box_gap (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GtkShadowType shadow,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ GtkPositionType gap_side,
+ gint gap_start,
+ gint gap_width)
+{
+ GceNode *node;
+ GceNode *base;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->shadow = gce_maps_get_shadow (shadow);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "box";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->shadow = base->shadow;
+ node->flavor = UNSET;
+
+ gap (self, node, base, window, area, widget,
+ x, y, width, height, gap_side, gap_start, gap_width);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+}
+
+static void
+draw_extension (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GtkShadowType shadow,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ GtkPositionType gap_side)
+{
+ GceNode *node;
+ GceNode *base;
+ gint gap_width;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->shadow = gce_maps_get_shadow (shadow);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "extension";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->shadow = base->shadow;
+ node->flavor = UNSET;
+
+ switch (gap_side) {
+ case GTK_POS_LEFT:
+ case GTK_POS_RIGHT:
+ gap_width = height;
+ break;
+ case GTK_POS_TOP:
+ case GTK_POS_BOTTOM:
+ gap_width = width;
+ break;
+ }
+
+ gap (self, node, base, window, area, widget,
+ x, y, width, height, gap_side, 0, gap_width);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+}
+
+static void
+draw_slider (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GtkShadowType shadow,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ GtkOrientation orientation)
+{
+ GceNode *node;
+ GceNode *base;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->shadow = gce_maps_get_shadow (shadow);
+ base->orientation = gce_maps_get_orientation (orientation);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "slider";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->shadow = base->shadow;
+ node->orientation = base->orientation;
+ node->flavor = UNSET;
+
+ rectangle (self, node, base, window, area, widget,
+ x, y, width, height, TRUE);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+}
+
+static void
+draw_handle (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GtkShadowType shadow,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ GtkOrientation orientation)
+{
+ GceNode *node;
+ GceNode *base;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->shadow = gce_maps_get_shadow (shadow);
+ base->orientation = gce_maps_get_orientation (orientation);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "handle";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->shadow = base->shadow;
+ node->orientation = base->orientation;
+ node->flavor = UNSET;
+
+ rectangle (self, node, base, window, area, widget,
+ x, y, width, height, TRUE);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+}
+
+static void
+draw_resize_grip (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ GdkWindowEdge edge,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GceNode *node;
+ GceNode *base;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->edge = gce_maps_get_window_edge (edge);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "resizegrip";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->edge = base->edge;
+ node->flavor = UNSET;
+
+ rectangle (self, node, base, window, area, widget,
+ x, y, width, height, TRUE);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+}
+
+static void
+draw_focus (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GceNode *node;
+ GceNode *base;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "focus";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->flavor = UNSET;
+
+ rectangle (self, node, base, window, area, widget,
+ x, y, width, height, FALSE);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+}
+
+static void
+draw_expander (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ gint x,
+ gint y,
+ GtkExpanderStyle style)
+{
+#define DEFAULT_EXPANDER_SIZE 12
+ GceNode *node;
+ GceNode *base;
+ gint expander_size;
+
+ if (widget &&
+ gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
+ "expander-size")) {
+ gtk_widget_style_get (widget,
+ "expander-size", &expander_size,
+ NULL);
+ } else {
+ expander_size = DEFAULT_EXPANDER_SIZE;
+ }
+
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->expander_style = gce_maps_get_expander_style (style);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "expander";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->expander_style = base->expander_style;
+ node->flavor = UNSET;
+
+ rectangle (self, node, base, window, area, widget,
+ x, y, expander_size, expander_size, TRUE);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+#undef DEFAULT_EXPANDER_SIZE
+}
+
+static void
+draw_diamond (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GtkShadowType shadow,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GceNode *node;
+ GceNode *base;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->shadow = gce_maps_get_shadow (shadow);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "diamond";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->shadow = base->shadow;
+ node->flavor = UNSET;
+
+ rectangle (self, node, base, window, area, widget,
+ x, y, width, height, TRUE);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+}
+
+static void
+draw_arrow (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GtkShadowType shadow,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ GtkArrowType arrow,
+ gboolean fill,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GceNode *node;
+ GceNode *base;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->shadow = gce_maps_get_shadow (shadow);
+ base->orientation = gce_maps_get_arrow (arrow);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "arrow";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->shadow = base->shadow;
+ node->orientation = base->orientation;
+ node->flavor = UNSET;
+
+ rectangle (self, node, base, window, area, widget,
+ x, y, width, height, TRUE);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+}
+
+static void
+draw_tab (GtkStyle *self,
+ GdkWindow *window,
+ GtkStateType state,
+ GtkShadowType shadow,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char const *detail,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GceNode *node;
+ GceNode *base;
+
+ base = node_cache_push (&_node_cache);
+ base->widget = widget;
+ base->class_name = gce_maps_get_detail (detail);
+ base->pseudo_class = gce_maps_get_state (state);
+ base->shadow = gce_maps_get_shadow (shadow);
+ base->flavor = PRIMITIVE;
+ base->impl.primitive = "tab";
+
+ node = node_cache_push (&_node_cache);
+ node->widget = widget;
+ node->class_name = base->class_name;
+ node->pseudo_class = base->pseudo_class;
+ node->shadow = base->shadow;
+ node->flavor = UNSET;
+
+ rectangle (self, node, base, window, area, widget,
+ x, y, width, height, TRUE);
+
+ node_cache_pop (&_node_cache);
+ node_cache_pop (&_node_cache);
+}
+
+static void
+instance_init (GceStyle *self)
+{
+
+}
+
+static void
+class_init (GceStyleClass *klass)
+{
+ GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
+
+ gce_style_parent_class = g_type_class_peek_parent (klass);
+
+ style_class->draw_hline = draw_hline;
+ style_class->draw_vline = draw_vline;
+ style_class->draw_shadow = draw_shadow;
+ /*
+ draw_polygon
+ */
+ style_class->draw_arrow = draw_arrow;
+ style_class->draw_diamond = draw_diamond;
+ style_class->draw_box = draw_box;
+ style_class->draw_flat_box = draw_flat_box;
+ style_class->draw_check = draw_check;
+ style_class->draw_option = draw_option;
+ style_class->draw_tab = draw_tab;
+ style_class->draw_shadow_gap = draw_shadow_gap;
+ style_class->draw_box_gap = draw_box_gap;
+ style_class->draw_extension = draw_extension;
+ style_class->draw_focus = draw_focus;
+ style_class->draw_slider = draw_slider;
+ style_class->draw_handle = draw_handle;
+ style_class->draw_expander = draw_expander;
+/*
+draw_layout
+*/
+ style_class->draw_resize_grip = draw_resize_grip;
+}
+
+void
+gce_style_register_type (GTypeModule *module)
+{
+ if (!gce_style_type) {
+ static const GTypeInfo info = {
+ sizeof (GceStyleClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GceStyle),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) instance_init,
+ };
+
+ gce_style_type = g_type_module_register_type (module,
+ GTK_TYPE_STYLE,
+ "GceStyle",
+ &info, 0);
+ }
+}
+
+GType
+gce_style_get_type (void)
+{
+ return gce_style_type;
+}
Added: bzr-playground/src/gce-style.h
==============================================================================
--- (empty file)
+++ bzr-playground/src/gce-style.h Mon Aug 18 13:50:33 2008
@@ -0,0 +1,46 @@
+/* Gtk CSS Engine
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GCE_STYLE_H
+#define GCE_STYLE_H
+
+#include <ccd/ccd.h>
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GCE_TYPE_STYLE (gce_style_get_type ())
+#define GCE_STYLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GCE_TYPE_STYLE, GceStyle))
+#define GCE_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCE_TYPE_STYLE, GceStyleClass))
+#define GCE_IS_STYLE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GCE_TYPE_STYLE))
+#define GCE_IS_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCE_TYPE_STYLE))
+#define GCE_STYLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCE_TYPE_STYLE, GceStyleClass))
+
+typedef struct _GceStyle GceStyle;
+typedef struct _GceStyleClass GceStyleClass;
+
+ccd_node_class_t const * gce_style_get_ccd_node_class (void);
+
+void gce_style_register_type (GTypeModule *module);
+GType gce_style_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* GCE_STYLE_H */
Added: bzr-playground/src/gce-theme.c
==============================================================================
--- (empty file)
+++ bzr-playground/src/gce-theme.c Mon Aug 18 13:50:33 2008
@@ -0,0 +1,61 @@
+/* Gtk CSS Engine
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <ccd/ccd.h>
+#include <gmodule.h>
+#include <gtk/gtk.h>
+
+#include "gce-style.h"
+#include "gce-rc-style.h"
+
+/* This prototypes silence some warnings. */
+G_MODULE_EXPORT void theme_init (GTypeModule *module);
+G_MODULE_EXPORT void theme_exit (void);
+G_MODULE_EXPORT GtkRcStyle * theme_create_rc_style (void);
+G_MODULE_EXPORT const gchar * g_module_check_init (GModule *module);
+
+G_MODULE_EXPORT void
+theme_init (GTypeModule *module)
+{
+ gce_rc_style_register_type (module);
+ gce_style_register_type (module);
+
+ ccd_init (gce_style_get_ccd_node_class ());
+}
+
+G_MODULE_EXPORT void
+theme_exit (void)
+{
+ ccd_shutdown ();
+}
+
+G_MODULE_EXPORT GtkRcStyle*
+theme_create_rc_style (void)
+{
+ return GTK_RC_STYLE (g_object_new (GCE_TYPE_RC_STYLE, NULL));
+}
+
+G_MODULE_EXPORT const gchar*
+g_module_check_init (GModule *module)
+{
+ return gtk_check_version (GTK_MAJOR_VERSION,
+ GTK_MINOR_VERSION,
+ GTK_MICRO_VERSION - GTK_INTERFACE_AGE);
+}
+
Added: bzr-playground/themes/Makefile.am
==============================================================================
--- (empty file)
+++ bzr-playground/themes/Makefile.am Mon Aug 18 13:50:33 2008
@@ -0,0 +1,3 @@
+
+SUBDIRS = gtk-css-test
+
Added: bzr-playground/themes/gtk-css-test/Makefile.am
==============================================================================
--- (empty file)
+++ bzr-playground/themes/gtk-css-test/Makefile.am Mon Aug 18 13:50:33 2008
@@ -0,0 +1,2 @@
+
+SUBDIRS = gtk-2.0
Added: bzr-playground/themes/gtk-css-test/gtk-2.0/Makefile.am
==============================================================================
--- (empty file)
+++ bzr-playground/themes/gtk-css-test/gtk-2.0/Makefile.am Mon Aug 18 13:50:33 2008
@@ -0,0 +1,7 @@
+
+themedir = $(datadir)/themes/gtk-css-test/gtk-2.0
+theme_DATA = \
+ gtkrc \
+ styles.css
+
+EXTRA_DIST = $(theme_DATA)
Added: bzr-playground/themes/gtk-css-test/gtk-2.0/gtkrc
==============================================================================
--- (empty file)
+++ bzr-playground/themes/gtk-css-test/gtk-2.0/gtkrc Mon Aug 18 13:50:33 2008
@@ -0,0 +1,12 @@
+style "default"
+{
+ xthickness = 1
+ ythickness = 1
+
+ engine "css"
+ {
+ href = "styles.css"
+ }
+}
+widget_class "*" style "default"
+
Added: bzr-playground/themes/gtk-css-test/gtk-2.0/styles.css
==============================================================================
--- (empty file)
+++ bzr-playground/themes/gtk-css-test/gtk-2.0/styles.css Mon Aug 18 13:50:33 2008
@@ -0,0 +1,130 @@
+/*
+box {
+ background-color: yellow;
+ border: 1px dashed green;
+ border-bottom: 2px solid red;
+}
+
+box:prelight {
+ background-color: red;
+}
+
+box.bar {
+ background-color: orange;
+}
+
+hline {
+ border: 2px solid black;
+}
+
+vline {
+ border: 2px solid brown;
+}
+
+GtkButton {
+ background-color: blue;
+}
+
+GtkButton:prelight {
+ background-color: green;
+}
+
+GtkToggleButton {
+ background-color: lightblue;
+}
+
+GtkComboBox GtkButton {
+ background-color: lightgreen;
+}
+
+GtkVBox GtkButton {
+ background-color: indigo;
+}
+
+GtkScrollbar box {
+ background-color: lightgreen;
+}
+
+GtkScrollbar box.trough {
+ background-color: darkgreen;
+}
+
+GtkCheckButton check.checkbutton {
+ background-color: white;
+}
+*/
+
+arrow {
+ background-color: black;
+}
+
+tab {
+ background-color: blue;
+}
+
+option {
+ background-color: red;
+}
+
+check {
+ background-color: green;
+}
+
+box {
+ background-color: darkkhaki;
+ border: 1px solid black;
+}
+
+flatbox {
+ background-color: darkkhaki;
+ border: 1px solid black;
+}
+
+GtkEntry flatbox {
+ background-color: darkkhaki;
+ border: none;
+}
+
+shadow {
+ background-color: khaki;
+ border: 1px solid black;
+}
+
+GtkEntry shadow {
+ background-color: darkkhaki;
+}
+
+slider {
+ background-color: orange;
+ border: 1px solid black;
+}
+
+extension {
+ border: 1px solid black;
+}
+
+focus {
+ border: 2px dotted yellow;
+}
+
+handle {
+ border: 1px dashed blue;
+}
+
+handle[orientation=vertical] {
+ background-color: gray;
+ border-left: 3px solid blue;
+}
+
+resizegrip[edge=south-east] {
+ border-right: 2px solid blue;
+ border-bottom: 2px solid blue;
+}
+
+GtkMenuBar {
+ border-bottom: none;
+}
+
+GtkProgressBar:prelight {
+ background-color: yellow;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]