[cairo] Cairo - PDF backend
Carl Worth
cworth at cworth.org
Sat Jun 24 13:33:11 PDT 2006
On Sat, 24 Jun 2006 17:29:12 +0200, "=?ISO-8859-1?Q?Mikl=F3s_Erd=E9lyi?=" wrote:
>
> By the excuse of Google's SoC I started doing Inkscape's PDF export with Cairo.
> The Cairo library is really fun to use, so the simple things like
> filling with solid color, setting stroking style has been implemented
> quickly.
>
Fantastic! I knew cairo was getting some SoC help through mozilla, but
I hadn't also expected to get some through inkscape. I think it's
wonderful that you're hooking inkscape and cairo up. And I'm truly
delighted to hear that you're having fun with cairo. That's definitely
my favorite reaction.
> Now I'm struck with drawing linear/radial gradients, because they just
> don't work. The first problem was that because _pattern_supported said
> gradient patterns aren't supported, the output was always an image
> fallback. So I re-enabled native gradients which resulted in no
> visible output. The interpolation functions and other stuff are well
> exported but the painting/filling itself doesn't produce any visible
> output (I'm testing with a simple linear gradient from cairo-snippets'
> gradient.cairo).
And I think it's great that you're looking at improving this code. It
should be fairly straightforward to get something going right
away. The history is that Kristian did all the original work on the
gradients---and that code handled a lot of the most important cases,
(such as 2-color-stop gradients) but not everything cairo could throw
at it.
At the time, we didn't have the good analysis support that we have now
and I just disabled the gradient code (with the UNSUPPORTED return
value you found). Now that we have all the analysis stuff in place
what you should do is characterize the functionality of the code and
correctly return UNSUPPORTED from _pattern_supported if the code is
known to not handle particular cases. Then we can incrementally
improve things from there.
> I tried changing to shading dictionaries but still there's no
> output,
As for debugging why the gradient code isn't working at all, I suspect
it's just some minor bit-rot, (I have shaken up the PDF surface
implementation a time or two since disabling the gradient code).
> Please help me with some ideas regarding the cause of this problem (it
> might just be related to me not getting the PDF spec right). I know
> you're an expert in PDF, so that's why I turned to you :)
> Thank you in advance. I'm looking forward to your answer.
I'm definitely not a PDF expert, but I will give you some debugging
strategies I've come up with. For PostScript stuff I start with broken
output and manually tweak it until it works. With PDF, manual editing
often ends up being more trouble than it's worth, (there are tricks
like emitting lots of extra whitespace into content streams and then
typing in overwrite mode so that the stream length is undisturbed).
But what really helps is to get your hands on a minimal, working PDF
file that is as close as possible to what you are trying to
achieve. And that should be pretty easy in your case since cairo
definitely did do what you want (for simple cases at least) in the
past.
So all you need to do is take your simple gradient-using,
PDF-generating program that is currently failing and then run it
against an old version of cairo that had working PDF gradients. To do
that you would do something like the following in your git clone of
cairo (please pardon me for launching into one of my mini git
tutorials here).
1) Start with a clean tree. Certain git commands, (as we will be using
in step 2), really need a clean tree to start with. You can get
this clean tree in several different ways, depending on your
mood. These are ordered as least-learning-required first, so you
can just stop reading if you get burned out. But the real gems are
at the end...
a) Tree is already clan to start with
You might be lucky and already have a clean tree. You can check
with git-status which will report if you've modified any files
under version control. If so, (and I think you do since you've
described some changes you've made to the PDF code), then this
is the "dirty" state we need to get rid of.
b) Throw away dirty state permanently
If you never want to see the code again you can throw it away
permanently with "git reset --hard". That's an important
command to know, but it's often not what you really want. We're
dealing with a case of one piece of work getting interrupted by
another, (you need to explore the old state of cairo to
develop the new), so you don't really want to throw things away
and start over. Keep reading:
c) Make a new clone of cairo from scratch
You could just git-clone a fresh clone of cairo from
cairographics.org. This doesn't require you to learn anything
new, (but what's the fun of that?), but this is also horribly
slow. You haven't read a really good solution yet.
d) Make a local clone of your existing repository:
cd ..
git clone -l -s cairo cairo-old-working-gradients
That's _really_ fast, and it's maybe a very natural approach if
you're used to keep separate branches in separate
directories. So this is the first workable approach to dealing
with dirty files that happen to be "in the way".
This approach does have drawbacks though. For example, git
configuration like .git/remotes doesn't get cloned/shared so if
you use lots of separate repositories you end up having to
manually copy configuration changes around. That's annoying. So
my preferred approach is to work within a single git
repository:
d) Commit good work to a new branch
If the local modifications you have are in a good state, then
they belong on their own branch, so come up with a logical name
for the branch and let them live there:
git checkout -b descriptive-branch-name
git commit -a -m "Description of change"
That's definitely good advice, and its what you should be doing
already as soon as you have good code. But sometimes you need
to get to a clean working tree even when you're in the middle
of making a mess of the code. The code doesn't work, so it's
not an interesting state to commit and describe. But you want
to stash it somewhere and get back to it later:
a) Commit local changes to a temporary (stash) branch:
git checkout -b stash
git commit -a -m stash
So the commands here are basically the same as in step (e)
above. The difference comes in when you want to come back to
the work. If you had made a "real" branch you would get back to
work by simply checking it out and then going from there. But
with this stash commit, you don't actually want to build off of
it. An easy thing to do is to checkout the actual branch of
interest, (master, for example), and then re-apply the stashed
change with:
git cherry-pick -r stash
Then clean up the stash branch which we don't need anymore:
git branch -D stash
[Finally, I should comment that what I really think should happen in
git is that all commands are fixed to never require a clean tree to
start with. Instead the dirty state of the tree should be able to be
left behind as state stored in the branch being switched away
from. Then when switching back to the branch, the dirty state would be
restored. This would basically just be a little bit of automation of
my step (e)]
OK, that was a big aside, but now, to what you were asking about
2) checkout an old state of cairo that is expected to work
The checkout command needs a branch name, (even though you don't
plan on committing on it), so choose something that describes why
you're exploring the history:
git checkout -b working-gradient <commit>
The question then is what commit to use. I think just using the
state of the PDF code as of the last stable release (1.0.4) should
work just fine. So try:
git checkout -b working-gradient 1.0.4
3) Build that, then run your test program against it.
Hopefully at this point you will get a working example of a
cairo-generated PDF file with a gradient and you can figure out
from looking at that output what should be changed in the current
code.
4) Maybe examine other states in the tree
If that doesn't do what you want, another point to look at would be
the state of the tree just before I started reworking everything
about how PDF is implemented. I found that by browsing through the
output of "git log -- src/cairo-pdf-surface.c". I've quoted below
an interesting part of that output: My c23d7d4758 commit is when
the gradients effectively got disabled and they haven't come back
yet. Interestingly, the two previous changes to the PDF code,
(6995a835972 and 5ac6e85455fce) specifically changed the
gradients. So that's probably the last time this code was touched,
so you might want to get familiar with those commits, (just use
"git show <commit>" to examine any one.) And you might even want to
look at the state of the tree just before those two changes,
(6ba777213).
So if you want to look at these states, you'll need a slightly
different command. You can't use "git checkout -b
working-gradient" again since the working-gradient branch has
already been created, (and you're on it). Instead you can just move
the working-gradient branch to a different point with:
git reset --hard <commit>
Warning: "git reset --hard" will destroy any dirty state you have
in files. That's why I went through all that explanation in step 1
to make sure you put that somewhere safe so it wouldn't get lost
here.
I hope that helps,
-Carl
commit c23d7d4758c7915505437b0fc8b57df9ef628289
Author: Carl Worth <cworth at cworth.org>
Date: Wed Jan 11 11:53:33 2006 +0000
Note that from here on out, the PDF output should always pass the
entire test suite!
Add new functions needed by users of cairo_paginated_surface_t.
Always snapshot a paginated surface to an image surface, rather
than a surface similar to the target. We do this since paginated
target surfaces are allowed to not b Switch the implementation
of cairo_pdf_surface_t to use cairo_paginated_surface_t. For now
this means that all PDF output is fallback images, but this can
change inc
commit 6995a83597217bd422e74d79ce3c989334ada871
Author: David Reveman <davidr at novell.com>
Date: Thu Jan 5 15:00:37 2006 +0000
Gradient updates in SVG backend and no sorting of color stops in
SVG or PDF backend
commit 5ac6e85455fce862989033d5ff98576d159664bd
Author: David Reveman <davidr at novell.com>
Date: Thu Jan 5 05:06:50 2006 +0000
Update gradient code in PDF backend
commit 6ba7772138d5ce64cef13b296cb61f94b49f9c24
Author: Christian Biesinger <cbiesinger at web.de>
Date: Fri Dec 16 03:02:35 2005 +0000
Globally rename "operator" to "op", to allow writing backends in
C++
reviewed by: cworth
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20060624/c0db4912/attachment.pgp
More information about the cairo
mailing list