[cairo] Re: cairo_get_current_point bug ?

Behdad Esfahbod behdad at behdad.org
Thu Oct 5 09:57:05 PDT 2006


On Thu, 2006-09-28 at 15:43 -0700, Carl Worth wrote:

> Let's look at what happens with a current point that is locked into a
> device-space origin of (0,0) when the context is created.

Actually I found a real-world example of when the current behavior of
returning (0,0) in user-space is assumed.  Read below.


> First, let's assume we create a path with a relative path-construction
> operation as the first operation, (since these are the only operations
> that care about the current point). That is, our path creation might
> consists of simply:
> 
> 	cairo_rel_line_to (cr, 5, 5);
> 
> Which, given an identity CTM, we all agree should result in a path
> consisting of MOVE_TO (0, 0) and LINE_TO (5, 5), right?
> 
> Now, let's suppose that that path creation exists inside an
> application function and that the calling function wants to transform
> it, (with a simple translation, for example). That is, the final path
> creation will look like:
> 
> 	cairo_translate (cr, x, y);
> 	cairo_rel_line_to (cr, 5, 5);
> 
> With your device-space current point you end up with a path of MOVE_TO
> (0, 0) and LINE_TO (x+5, y+5), right? That's nothing like a translated
> version of the path.

Why?  I don't understand this last paragraph.  First, a
cairo_rel_line_to should not be affected by cairo_translate().  So,
expecting it to move the path is bogus in the first place.  Second, how
do you get that LINE_TO (x+5, y+5)?  That doesn't look like relative to
me.  For rel_line_to, you get current point in device space, convert
rel_line_to parameters to device space using user_to_device_distance(),
and add.

> However, my rule of making cairo_rel_line_to have an implicit move_to
> (cr, 0, 0) when there's no current point means that the resulting path
> is a translated version of the original, (MOVE_TO (x, y) and LINE_TO
> (x+5, y+5)).

In fact, this is inconsistent in that if there is no current point, a
translate affects a rel_line_to, but if there is a current point, it
doesn't.


A more realistic example, and one that I actually wrote in dasher on the
day I came out of your cairo tutorial is this:

  cairo_translate(cr, x1, y1-(int)m_pPangoInk->height/2);
  pango_cairo_show_layout(cr, pLayout);

Writing that, I didn't check docs and didn't know that
pango_cairo_show_layout renders the layout at current point.  So, I
thought to myself "ok, there's no (x,y) for where to show the layout,
so, how do I draw it where I want?  Aha!  I translate!"  And that works
exactly because we return user-space (0,0) in get_current_point() if
there's no current point.


So, looking back at the thread now, I suggest we go for:

cairo_status_t
cairo_get_current_point (cr, *x, *y);

and document it as setting x,y to zero if there is any error.  Remaining
questions to answer are:

  * What if cr is in an error state?  Do we return that and set x,y to
zero, or work normally?

  * Didn't get an answer to this: what should language bindings do?
They probably cannot start throwing an exception if there is no current
point.  Should they add a has_current_point() method?  What about other
errors that cairo_get_current_point() may return?


> Am I missing anything?
> 
> -Carl
-- 
behdad
http://behdad.org/

"Commandment Three says Do Not Kill, Amendment Two says Blood Will Spill"
        -- Dan Bern, "New American Language"



More information about the cairo mailing list