[cairo] SVG backend patch
krh at bitplanet.net
Mon Aug 1 19:50:04 PDT 2005
Emmanuel Pacaud wrote:
>>surface->fill_path() is working. Next steps could be to get
>>emit_solid_pattern() working. Also, getting composite_trapezoids()
>>working would make strokes work, so that's also worth looking into. I'm
>>thinking that the 'polygon' element would work well for trapezoids.
> You'll find attached the next iteration of my work in progress patch. It
> adds support for composite_trapezoids. As composite trapezoids will not
> produce acceptable SVG, I've also added an early fallback for stroke,
> and the corresponding function in SVG backend.
I agree, it should be possible to output strokes as svg stroked paths,
but it's one of those things we've been discussing back and forth. The
short story is that stroking a path is hard and most ps/pdf/svg
renderers expose some bugs and misrenderings when you go to extremes
(very thick stroked paths doing sharp bends). Cairo's algorithm for
stroking paths is fairly simple and roboust, and by outputting the
trapezoids, cairo output will look good even in renderers that have
problems with these corner cases.
Now, outputting the trapezoids creates a huge and uneditable svg file,
and is not what we want in any case. Right now the stroking algorithm
produces trapezoids directly, but the goal is to rewrite it to produce a
new path that is the outline of the stroke and then fill that path.
With this in place, the PDF, PS and SVG backends need not implement
composite_trapezoids, since all drawing will go through fill_path. Even
so, I think that stroke_path is a backend function that we want and I
think there should be a way for the user to specify wether strokes
shoudl be output as strokes or fills.
>>Text is probably going to be a bit more tricky, since the svg text
>>operators seem more highlevel than the show_glyphs() cairo backend
> Will work on it after basic drawing is in place.
>>And I'm not sure what's the right thing to do for fonts - we
>>could certainly generated an svg font subset to embed in the svg file,
>>but I'm not sure how many svg viewers support that, and we loose hinting
>>when we do that.
> I guess viewers should be smart enough to use a local font instead of
> embeded one.
We'll see how it works out. My concern is that all other cairo backends
generate output that looks identical regardless of the environment.
If we rely on the font being available on the system were the svg is
viewed we're breaking from this rule. But maybe that's acceptable for svg.
> What is also new in this version is the use of libxml. Please tell me if
> you feel this is wrong (or anything else in the patch).
I'm not convinced that we need libxml. It's a big, somewhat political
dependency, and we won't be using very much of it. I think that
instead, if you feel that the cairo_output_stream_t API is awkward, you
should look into adding the convenience functions you need, for example
cairo_output_stream_print_tag (stream, "path", "style", style, NULL);
even though that example doesn't seem too useful to me :-) What I was
thinking of was something like
cairo_output_stream_printf (stream, "<path");
emit_pattern (pattern, stream);
cairo_output_stream_printf (stream, "/>\n");
and in emit_pattern:
cairo_output_stream_printf (stream, " style=\"color: red;\");
A general comment: the cairo indent style is 4 spaces and further
documented in the CODING_STYLE file.
> +_cairo_surface_stroke (cairo_operator_t operator,
> + cairo_pattern_t *pattern,
> + cairo_surface_t *dst,
> + cairo_path_fixed_t *path,
> + double line_width,
> + cairo_line_cap_t line_cap,
> + cairo_line_join_t line_join,
> + double miter_limit,
> + double *dash,
> + int num_dashes,
> + double dash_offset,
> + cairo_matrix_t *ctm_inverse)
> + if (dst->backend->stroke)
> + return dst->backend->stroke (operator, pattern, dst, path,
> + line_width, line_cap, line_join, miter_limit,
> + dash, num_dashes, dash_offset, ctm_inverse);
> + else
> + return CAIRO_INT_STATUS_UNSUPPORTED;
The name of the function shold be stroke_path, i.e.
_cairo_surface_stroke_path and backend->stroke_path to match up with
fill_path. Also, I've been thinking that instead of passing around all
the line attributes (width, cap, join, miter limit, dashes) we could
group them in a cairo_line_attributes_t struct in cairo_gstate_t and
pass a pointer to that struct to _cairo_surface_stroke_path.
More information about the cairo