[cairo] Dia as a new Cairo testbed
Carl Worth
cworth at east.isi.edu
Mon Jul 5 08:25:49 PDT 2004
On Tue, 25 May 2004 14:32:04 +0200, Hans Breuer wrote:
> You can find some of the pain in the source marked by //FIXME:
> http://cvs.gnome.org/viewcvs/dia/plug-ins/cairo/diacairo.c?view=markup
> also some of it is mentioned in my other mail to Keith.
Sorry for the very tardy reply, but I'll comment now on some of what I
see there:
/*FIXME: I'd like this to clear the alpha background, but it doesn't work
* cairo_set_alpha (renderer->cr, 0.0);
*/
/* clear background */
cairo_set_rgb_color (renderer->cr, ...);
cairo_rectangle (renderer->cr, ...);
cairo_fill (renderer->cr);
/*FIXME : how is this supposed to work ?
* cairo_set_operator (renderer->cr, DIA_CAIRO_OPERATOR_SRC);
* cairo_set_alpha (renderer->cr, 1.0);
The default operator (CAIRO_OPERATOR_OVER) is the Porter/Duff OVER
operator. With that, setting alpha to 0 will cause the fill to have no
effect.
It looks like you want to explicitly set the destination to a value
rather than compositing with its current contents. And for that,
CAIRO_OPERATOR_SRC is what you want. So, it looks like you got close. If
you want to force the destination to alpha==0 you should be able to use
something like:
cairo_set_operator (renderer->cr, DIA_CAIRO_OPERATOR_SRC);
cairo_set_alpha (renderer->cr, 0.0);
/* clear background */
cairo_set_rgb_color (renderer->cr, ...);
cairo_rectangle (renderer->cr, ...);
cairo_fill (renderer->cr);
Next:
case FILLSTYLE_SOLID:
/* FIXME: how to set _no_ pattern ?
* cairo_set_pattern (renderer->cr, NULL);
*/
break;
Hmmm, we should make that usage do something natural. For now, you want
to call cairo_set_rgb_color to use a solid color rather than a pattern.
/* Dia and Cairo don't agree on arc definitions, so it needs
* to be converted, i.e. mirrored at the x axis
*/
That may be the case. Angles in cairo begin with 0 radians in the
direction of the positive X axis and increasing toward the positive Y
axis. The axes are oriented to match convential graphics systems,
(origin at the upper-left, X increasing to the right and Y increasing
down).
The cairo_arc function constructs a path from angle1 to angle2 in the
direction of increasing angles, while arc_negative constructs a path
from angle1 to angle2 in the direction of decreasing angles. In either
case, angle2 will be adjusted by multiples of 2*PI until it is
greater/lesser than angle1.
Hopefully that explanation helps. But it looks like you did succeed in
working out the conversion, (at least juding by the lack of "FIXME" in
the code).
/* FIXME: to handle width != height some cairo_scale/cairo_translate would be needed */
Here's one example of how to do this, (from cairo-demo/X11/cairo-knockout.c):
/* Create a path that is a circular oval with radii xr, yr centered at xc, yc */
static void
oval_path (cairo_t *cr,
double xc, double yc,
double xr, double yr)
{
cairo_matrix_t *matrix;
matrix = cairo_matrix_create ();
cairo_current_matrix (cr, matrix);
cairo_translate (cr, xc, yc);
cairo_scale (cr, 1.0, yr / xr);
cairo_move_to (cr, xr, 0.0);
cairo_arc (cr,
0, 0,
xr,
0, 2 * M_PI);
cairo_close_path (cr);
cairo_set_matrix (cr, matrix);
cairo_matrix_destroy (matrix);
}
Next:
/* FIXME: how to make a perfect ellipse from a bezier ? */
cairo_arc has the code to compute as many Bezier splines as needed in
order to approximate an arc within the current tolerance value. So, the
oval_path function above should be all you need, (should really be named
ellipse_path I suppose).
I hope that helps.
-Carl
More information about the cairo
mailing list