Summary: | inverse transformation of line width | ||
---|---|---|---|
Product: | cairo | Reporter: | Attila Babo <ababo> |
Component: | general | Assignee: | Carl Worth <cworth> |
Status: | RESOLVED WONTFIX | QA Contact: | cairo-bugs mailing list <cairo-bugs> |
Severity: | normal | ||
Priority: | high | CC: | billy.biggs |
Version: | 1.0.0 | ||
Hardware: | x86 (IA32) | ||
OS: | Windows (All) | ||
Whiteboard: | |||
i915 platform: | i915 features: |
Description
Attila Babo
2005-09-13 06:01:53 UTC
If you save and restore around the path creation, you will create a scaled path but draw with the current line width. cairo_set_line_width(cr, 1); // one pixel wide line cairo_save(cr); cairo_scale(cr, width, height); // window dimensions in pixel cairo_move_to(cr, 0.1, 0.1); // a rectangle in relative dimensions cairo_rel_line_to(cr, 0.8, 0); cairo_rel_line_to(cr, 0, 0.8); cairo_rel_line_to(cr, -0.8, 0); cairo_close_path(cr); cairo_restore(cr); Thank you for the workaround! My current solution is to use cairo_device_to_user() to apply the inverse transformation like this: double lw=cairo_get_line_width(cr); cairo_scale(cr, ..., ...); cairo_device_to_user(cr, &lw, &lw); cairo_set_line_width(cr, lw); This working fine, but it would be better to do it in the library level in cairo_scale automatically. Sorry, this is the correct code to keep the line width: double lw=cairo_get_line_width(cr); cairo_user_to_device_distance(cr, &lw, &lw); cairo_scale(cr, ..., ...); cairo_device_to_user(cr, &lw, &lw); cairo_set_line_width(cr, lw); Whether or not this change would be useful, it isn't a compatible change, and therefore we are unlikely ever to make it. (Making cairo_scale() *not* scale all aspects uniformly might also be suprising and hard to predict. Though I agree that wanting to scale coordinates for convenience but preserve line width is common.) WONTFIX due to incompatibility is the correct resolution. As for "better" it really could be argued in either direction as Owen suggests above. There are use cases for both scaling and not scaling the line width. Billy already volunteered one approach that allows for using transformations while creating a path without affecting the line width. Here's another alternative which you might find more suitable for your situation. Here's a way to set the line width in pixel dimensions just prior to stroking, regardless of what transformation has been in effect before: /* create path here using whatever scaling desired. */ cairo_save (cr); cairo_identity_matrix (cr); cairo_set_line_width (cr, width_in_pixels); cairo_stroke (cr); cairo_restore (cr); Good luck, and have fun! Talking about compatibility, please try out this code and explain the output. void lwt(HDC hdc, int width, int height) { cairo_surface_t *surface = cairo_win32_surface_create(hdc); cairo_t *cr = cairo_create(surface); cairo_rectangle(cr, width*0.1, height*0.1, width*0.8, height*0.8); cairo_stroke(cr); cairo_move_to(cr, width*0.2, height*0.2); cairo_scale(cr, width, height); cairo_rel_line_to(cr, 0.6, 0.0); cairo_rel_line_to(cr, 0.0, 0.6); cairo_rel_line_to(cr, -0.6, 0.0); cairo_rel_line_to(cr, 0.0, -0.6); cairo_rectangle(cr, 0.3, 0.3, 0.4, 0.4); cairo_stroke(cr); cairo_show_page(cr); cairo_destroy(cr); cairo_surface_destroy(surface); } Now add this line after the scale operation and try again. cairo_set_line_width(cr, 1.0/width); The scale doesn't effect the drawing position what I set before the transformation as expected, but changed the effective line width. Do you really like the current behaviour? The path is not part of the graphics state. That's how it works. |
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.