commit e47f899a3fb10558b78a150d666ea5c6ce9fffd3 Author: Brian Ewins Date: Tue Feb 20 02:08:51 2007 +0000 [nquartz] ensure that line widths are scaled. cairo-gstate applies the ctm to the coordinates used in paths, but not to the line width. In nquartz this ends up drawing unscaled lines. This is a minimal fix - it undoes the scaling applied to the points and then draws the path scaled correctly. diff --git a/src/cairo-nquartz-surface.c b/src/cairo-nquartz-surface.c index dd05c38..36296db 100644 --- a/src/cairo-nquartz-surface.c +++ b/src/cairo-nquartz-surface.c @@ -121,6 +121,10 @@ typedef struct cairo_nquartz_surface { #endif } cairo_nquartz_surface_t; +typedef struct cairo_nquartz_transformed_context { + CGContextRef cgContext; + cairo_matrix_t *ctm_inverse; +} cairo_nquartz_transformed_context_t; /** ** Utility functions **/ @@ -171,8 +175,12 @@ static cairo_status_t _cairo_path_to_quartz_context_move_to (void *closure, cairo_point_t *point) { //ND((stderr, "moveto: %f %f\n", _cairo_fixed_to_double(point->x), _cairo_fixed_to_double(point->y))); - CGContextMoveToPoint ((CGContextRef) closure, - _cairo_fixed_to_double(point->x), _cairo_fixed_to_double(point->y)); + cairo_nquartz_transformed_context_t *tc = + (cairo_nquartz_transformed_context_t *)closure; + double x = _cairo_fixed_to_double (point->x); + double y = _cairo_fixed_to_double (point->y); + cairo_matrix_transform_point (tc->ctm_inverse, &x, &y); + CGContextMoveToPoint (tc->cgContext, x, y); return CAIRO_STATUS_SUCCESS; } @@ -180,12 +188,15 @@ static cairo_status_t _cairo_path_to_quartz_context_line_to (void *closure, cairo_point_t *point) { //ND((stderr, "lineto: %f %f\n", _cairo_fixed_to_double(point->x), _cairo_fixed_to_double(point->y))); - if (CGContextIsPathEmpty ((CGContextRef) closure)) - CGContextMoveToPoint ((CGContextRef) closure, - _cairo_fixed_to_double(point->x), _cairo_fixed_to_double(point->y)); + cairo_nquartz_transformed_context_t *tc = + (cairo_nquartz_transformed_context_t *)closure; + double x = _cairo_fixed_to_double (point->x); + double y = _cairo_fixed_to_double (point->y); + cairo_matrix_transform_point (tc->ctm_inverse, &x, &y); + if (CGContextIsPathEmpty (tc->cgContext)) + CGContextMoveToPoint (tc->cgContext, x, y); else - CGContextAddLineToPoint ((CGContextRef) closure, - _cairo_fixed_to_double(point->x), _cairo_fixed_to_double(point->y)); + CGContextAddLineToPoint (tc->cgContext, x, y); return CAIRO_STATUS_SUCCESS; } @@ -196,11 +207,20 @@ _cairo_path_to_quartz_context_curve_to (void *closure, cairo_point_t *p0, cairo_ // _cairo_fixed_to_double(p0->x), _cairo_fixed_to_double(p0->y), // _cairo_fixed_to_double(p1->x), _cairo_fixed_to_double(p1->y), // _cairo_fixed_to_double(p2->x), _cairo_fixed_to_double(p2->y))); - - CGContextAddCurveToPoint ((CGContextRef) closure, - _cairo_fixed_to_double(p0->x), _cairo_fixed_to_double(p0->y), - _cairo_fixed_to_double(p1->x), _cairo_fixed_to_double(p1->y), - _cairo_fixed_to_double(p2->x), _cairo_fixed_to_double(p2->y)); + cairo_nquartz_transformed_context_t *tc = + (cairo_nquartz_transformed_context_t *)closure; + double x0 = _cairo_fixed_to_double (p0->x); + double y0 = _cairo_fixed_to_double (p0->y); + double x1 = _cairo_fixed_to_double (p1->x); + double y1 = _cairo_fixed_to_double (p1->y); + double x2 = _cairo_fixed_to_double (p2->x); + double y2 = _cairo_fixed_to_double (p2->y); + cairo_matrix_transform_point (tc->ctm_inverse, &x0, &y0); + cairo_matrix_transform_point (tc->ctm_inverse, &x1, &y1); + cairo_matrix_transform_point (tc->ctm_inverse, &x2, &y2); + + CGContextAddCurveToPoint (tc->cgContext, + x0, y0, x1, y1, x2, y2); return CAIRO_STATUS_SUCCESS; } @@ -208,7 +228,9 @@ static cairo_status_t _cairo_path_to_quartz_context_close_path (void *closure) { //ND((stderr, "closepath\n")); - CGContextClosePath ((CGContextRef) closure); + cairo_nquartz_transformed_context_t *tc = + (cairo_nquartz_transformed_context_t *)closure; + CGContextClosePath (tc->cgContext); return CAIRO_STATUS_SUCCESS; } @@ -1216,6 +1238,8 @@ _cairo_nquartz_surface_fill (void *abstract_surface, cairo_nquartz_surface_t *surface = (cairo_nquartz_surface_t *) abstract_surface; cairo_int_status_t rv = CAIRO_STATUS_SUCCESS; cairo_nquartz_action_t action; + cairo_nquartz_transformed_context_t transformed_context; + cairo_matrix_t ctm_inverse; ND((stderr, "%p _cairo_nquartz_surface_fill op %d source->type %d\n", surface, op, source->type)); @@ -1234,7 +1258,10 @@ _cairo_nquartz_surface_fill (void *abstract_surface, } CGContextBeginPath (surface->cgContext); - _cairo_nquartz_cairo_path_to_quartz_context (path, surface->cgContext); + transformed_context.cgContext = surface->cgContext; + cairo_matrix_init_identity (&ctm_inverse); + transformed_context.ctm_inverse = &ctm_inverse; + _cairo_nquartz_cairo_path_to_quartz_context (path, &transformed_context); if (action == DO_SOLID || action == DO_PATTERN) { if (fill_rule == CAIRO_FILL_RULE_WINDING) @@ -1277,6 +1304,8 @@ _cairo_nquartz_surface_stroke (void *abstract_surface, cairo_nquartz_surface_t *surface = (cairo_nquartz_surface_t *) abstract_surface; cairo_int_status_t rv = CAIRO_STATUS_SUCCESS; cairo_nquartz_action_t action; + cairo_nquartz_transformed_context_t transformed_context; + CGAffineTransform theTransform; ND((stderr, "%p _cairo_nquartz_surface_stroke op %d source->type %d\n", surface, op, source->type)); @@ -1292,6 +1321,8 @@ _cairo_nquartz_surface_stroke (void *abstract_surface, CGContextSetLineCap (surface->cgContext, _cairo_nquartz_cairo_line_cap_to_quartz (style->line_cap)); CGContextSetLineJoin (surface->cgContext, _cairo_nquartz_cairo_line_join_to_quartz (style->line_join)); CGContextSetMiterLimit (surface->cgContext, style->miter_limit); + _cairo_nquartz_cairo_matrix_to_quartz (ctm, &theTransform); + CGContextConcatCTM (surface->cgContext, theTransform); if (style->dash && style->num_dashes) { #define STATIC_DASH 32 @@ -1319,7 +1350,9 @@ _cairo_nquartz_surface_stroke (void *abstract_surface, } CGContextBeginPath (surface->cgContext); - _cairo_nquartz_cairo_path_to_quartz_context (path, surface->cgContext); + transformed_context.cgContext = surface->cgContext; + transformed_context.ctm_inverse = ctm_inverse; + _cairo_nquartz_cairo_path_to_quartz_context (path, &transformed_context); if (action == DO_SOLID || action == DO_PATTERN) { CGContextStrokePath (surface->cgContext); @@ -1503,6 +1536,8 @@ _cairo_nquartz_surface_intersect_clip_path (void *abstract_surface, cairo_antialias_t antialias) { cairo_nquartz_surface_t *surface = (cairo_nquartz_surface_t *) abstract_surface; + cairo_nquartz_transformed_context_t transformed_context; + cairo_matrix_t ctm_inverse; ND((stderr, "%p _cairo_nquartz_surface_intersect_clip_path path: %p\n", surface, path)); @@ -1518,7 +1553,10 @@ _cairo_nquartz_surface_intersect_clip_path (void *abstract_surface, CGContextSaveGState (surface->cgContext); } else { CGContextBeginPath (surface->cgContext); - _cairo_nquartz_cairo_path_to_quartz_context (path, surface->cgContext); + transformed_context.cgContext = surface->cgContext; + cairo_matrix_init_identity (&ctm_inverse); + transformed_context.ctm_inverse = &ctm_inverse; + _cairo_nquartz_cairo_path_to_quartz_context (path, &transformed_context); if (fill_rule == CAIRO_FILL_RULE_WINDING) CGContextClip (surface->cgContext); else