I am working on supporting non-inline CSS stylesheets, by using libcroco (a C library for CSS parsing and determining what CSS properties apply to a given element).
Not quite: libcroco 0.6 (the most recent released version) isn't really suitable for Inkscape's use for finding what properties apply to a given element: it requires a libxml in-memory representation of the document tree rather than allowing use of our preferred Inkscape::XML::Node. (See near end of http://www.inkscape.org/cgi-bin/wiki.pl?CSS_Support for more details.)
I have prepared some modifications to libcroco to make this more suitable for us, and I've gradually been feeding patches to the libcroco maintainer, but that will take some time for all the changes just to reach CVS, let alone be released as libcroco 0.7, let alone be available on a reasonable number of our users' systems.
There are two main ways of addressing this that I'm considering:
i) Put our own version of the rule selection code (cr-sel-eng.{c,h}) into Inkscape, and make it play nice with an installed (external) copy of libcroco 0.6.
ii) Put all of libcroco into the Inkscape source tree.
For (i), there are two aspects of "playing nicely with installed libcroco":
- Getting `#include "cr-foo.h"' to find cr-foo.h (usually referenced from user apps as `#include <libcroco/cr-foo.h>').
The simplest approach is to change all `#include "cr-foo.h"' to `#include <libcroco/cr-foo.h>'. This is my preferred approach at the moment.
It's tempting to try instead to get `-I/usr/include/libcroco-0.6/libcroco' (or whatever the path on the user's system) into our INCLUDES variable. This approach would be pleasing in its simplicity, and would also slightly reduce work in merging changes back into upstream libcroco. However, given that the exact path varies from system to system, the best I can think of involves adding to configure.ac something like
ink_cr_incl=`pkg-config --cflags libcroco-0.6 | sed 's, .*,/libcroco ,'` INCLUDES="$INCLUDES $ink_cr_incl"
(while retaining libcroco-0.6 in a PKG_CHECK_MODULES call, which would take care of LDFLAGS and error handling). Not too big a deal, but then neither is the #include-changing alternative.
- Avoiding linkage errors from having cr-sel-eng symbols both in Inkscape's internal libraries and also in installed libcroco. Is there some linker options to avoid this? Otherwise, the alternatives are either to #define all the external symbols of our own cr-sel-eng to something else, or to convert cr-sel-eng.c to C++, which I believe should give different linker symbols (mangled); we could wrap in a namespace{} too if we want.
My local copy uses the convert-to-C++ approach. It involved adding explicit casts in a dozen or so places (no implicit cast from void* in C++, no treating enums as ints).
Approach (ii) has at least the following advantages & disadvantages:
Advantages:
- All libcroco source files can stay in C and can retain their existing #include text.
- It guarantees us that libcroco is available. Otherwise we must choose between either:
- Requiring libcroco (and bundling on some platforms with poor package management -- can't they all just use Debian? ;-) ); or
- Using `#ifdef WITH_LIBCROCO' in the source code, and accepting that not all builds of 0.42 (or whatever) will be able to read SVG files using non-inline style.
Disadvantages:
- Makes Inkscape source tree about 1MB bigger, and increases Inkscape's memory usage at runtime.
- Any bug fixes to libcroco would have to wait until at least one release of Inkscape before being fixed. This is most of concern if the bug fix is security-related.
Licensing doesn't seem to be a problem: libcroco appears to be LGPL.
I haven't yet checked with the libcroco maintainer for his comments; I'll bcc him.
Can people add to this list of advantages & disadvantes, or suggest alternatives, or give other relevant information?
pjrm.