[cairo] Re: cairo_get_current_point bug ?
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(),
> 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
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);
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_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?
"Commandment Three says Do Not Kill, Amendment Two says Blood Will Spill"
-- Dan Bern, "New American Language"
More information about the cairo