[GRASS-dev] Cairo monitor driver
Lars Ahlzen
lars at ahlzen.com
Tue Oct 16 20:05:39 EDT 2007
Glynn Clements wrote:
> I've committed [the cairo driver] to CVS, with a few changes; mostly, just
> conforming to existing coding and formatting conventions.
Thanks! I very much appreciate the time you obviously spent on looking
at the code, cleaning it up and adding it.
> The main one is that code should stick to ANSI C89...
>
> Variables which aren't used outside of the file in which they are
> defined should be declared "static".
Noted. I guess I should have enabled the -ansi flag in GCC.
> The only externally-visible change is that the driver and monitor
> names have been changed from "CAIRO" to "cairo" (the web site treats
> "cairo" as a normal word, i.e. all lower-case except in a title or at
> the beginning of a sentence). PNG and PS are upper-case as they are
> acronyms; XDRIVER is a historical artifact (and the monitor names are
> "x0" etc).
Makes perfect sense.
> A question about the set_drawing_op/finish_drawing_op stuff: is this
> meant to merge distinct line segments into a single path? If so, I'll
> remove it.
>
> The lack of begin/end operations for paths (move/cont) is a flaw in
> the interface, and is one of the planned interface changes for 7.x.
> Note that the PS driver doesn't attempt to hack around this; if you
> want a single path, you have to use the polyline operation.
Yes, it was primarily to ensure that lines are connected (for nice line
joins etc). But I guess you're right - that's what polyline is for.
I believe this means that pretty much all of drawing.c can go. One would
have to call cairo_stroke or cairo_fill directly from the drawing
functions instead.
> The global cairo_translate(cairo, 0.5, 0.5) is wrong. If you want to
> work around the problems with lines having their endpoints on pixel
> boundaries (rather than centres), apply the translation only to lines.
> Other operations (box/polygon fills, images, text) should *not* be
> translated in this way. FWIW, the PS driver doesn't even translate
> lines.
Well, this one is a little bit tricky.
You're right that filled shapes and images must not be translated to
remain sharp. However, this would not really produce a correct result
either (with correct being defined as similar to other drivers).
If ONLY lines were translated and nothing more was done, the 1/2 pixel
offset between lines and filled shapes would very likely cause issues
where lines and filled areas meet.
Furthermore, there's a problem with polygon size. Consider a case of a
filled rectangle from (10,2) to (20,3). Mathematically (and the way
Cairo sees things) this is a 10 units wide by 1 unit tall rectangle.
Pixel based drivers (PNG, X, etc) would draw an 11 pixel wide and 2
pixel tall rectangle. Cairo, assuming no translation, would draw a 10
pixel wide and 1 pixel tall rectangle. OTOH, with the translation and
antialiasing enabled, cairo would draw an 11 pixel wide and 2 pixel tall
rectangle, but with fuzzy edges (on a pixel-based "canvas"), which
seemed (and still seems) like the less bad of the two options to me.
So, why not just disable translation for filled rectangles and make them
one unit wider and taller (for pixel-based output)? This approach might
work for rectangles, but not for arbitrary shapes, such as a triangle -
at least not in any trivial way.
I don't believe that adding the offset to lines only would solve the
fundamental problem, or even really improve the situation, although I'm
happy to try it if you insist.
One could also forget about the whole offset thing and accept fuzzy
lines, knowing that this is only a problem because of the current lack
of floating point coordinates. It's either sharp lines or sharp filled
shapes. Having tried both, I personally much prefer the former, though.
Quoting from the official Cairo FAQ regarding fuzzy lines [1]:
"It is not possible to set up sample locations in a way so that both
fills and strokes with integer coordinates work nicely, so one had to be
preferred over the other. One argument in favor of preferring fills is
that all fills with integer coordinates align nicely this way. The best
that can be done with strokes is to make all even-integer-width strokes
align nicely (as they do in cairo) or to make odd-integer-width strokes
align (which would then break the fill alignment)."
[1] http://www.cairographics.org/FAQ/#sharp_lines
Regarding the comparison with the PS driver, note that the cairo driver
applies the translation ONLY for pixel-based formats (PNG). It doesn't
translate anything for PS output (or any other vector format) either.
> The use of pkg-config really belongs in the configure script...
>
> At present, the only way to enable the cairo driver is to manually set
> USE_CAIRO=1, e.g. "make USE_CAIRO=1".
Yes, the makefiles need work. Ideally, this should probably be a
configure option, i.e. ./configure --with-cairo
> The raster library should be extended to allow direct rendering via
> cairo, but we should get it working fully first.
>
> I note that clipping isn't enabled, and that the bitmap primitive
> (used for freetype text, amongst other things) is a no-op. Both of
> these are relatively important; the bitmap primitive would be less
> important if the driver implements the draw_text method using cairo's
> built-in font rendering.
> AFAICT, clipping should just be a matter of calling cairo_reset_clip()
> and cairo_clip(). Ignore the encapsulation issues; again, that's an
> interface flaw (which also affects the PS driver).
I agree, clipping and Draw_bitmap should be added ASAP. Neither should
be very difficult to implement.
Please prove me wrong here, but one of the problems I've had is that the
documentation on the monitor interface (such as driver struct) in the
Grass Programmer's manual is virtually nonexistent. Most of the cairo
driver work was done by looking at the PNG and PS drivers with some
trial-and-error thrown in. Does complete documentation for these areas
exist?
Given the text rendering support in Cairo, I hope that adding good
quality text rendering will be relatively straightforward as well.
I take it that the best thing for me to do right now would be to work on
the mentioned issues and missing features and post a patch? Perhaps
add basic documentation in display/drivers/cairo as well?
Again, thanks for the feedback!
/ Lars
--
Lars Ahlzen
lars at ahlzen.com
More information about the grass-dev
mailing list