[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