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.