[cairo-commit] 10 commits - NEWS src/cairo-atsui-font.c src/cairo-quartz-private.h src/cairo-quartz-surface.c
Brian Ewins
brianewins at kemper.freedesktop.org
Thu Jun 7 17:57:02 PDT 2007
NEWS | 3
src/cairo-atsui-font.c | 19 +-
src/cairo-quartz-private.h | 5
src/cairo-quartz-surface.c | 293 ++++++++++++++++++++++++++++++++-------------
4 files changed, 224 insertions(+), 96 deletions(-)
New commits:
diff-tree 8223c976d54319b58906de03fcb8fb1967105e53 (from 00063a65f758265f3ad5c0caa374d9c7d5e89932)
Author: Brian Ewins <Brian.Ewins at gmail.com>
Date: Fri Jun 8 01:56:10 2007 +0100
[NEWS] add note about quartz fixes
We've got 11 less failures in the quartz tests this time around,
worth a mention.
diff --git a/NEWS b/NEWS
index a2badde..a805bc9 100644
--- a/NEWS
+++ b/NEWS
@@ -52,6 +52,9 @@ Remove Xsun from the buggy_repeat blackl
ATSUI: Fix glyph measurement: faster and more correct (Brian Ewins)
+Quartz: fixed 'extend' behaviour for patterns, improved pattern performance,
+and a few smaller correctness fixes. (Brian Ewins, Vladimir Vukicevic)
+
Release 1.4.6 (2007-05-01 Carl Worth <cworth at cworth.org>)
=========================================================
This is the third update in cairo's stable 1.4 series. It comes a
diff-tree 00063a65f758265f3ad5c0caa374d9c7d5e89932 (from 39e6a0090faa4e73a658c1ca0ead3040309b84a2)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date: Fri Jun 8 01:17:09 2007 +0100
[quartz] fix DO_IMAGE
The implementation of DO_IMAGE leaks memory via a referenced surface,
and wasn't applied for strokes and glyphs. This patch corrects those
issues.
diff --git a/src/cairo-quartz-private.h b/src/cairo-quartz-private.h
index 23d7d4b..cd1b15c 100644
--- a/src/cairo-quartz-private.h
+++ b/src/cairo-quartz-private.h
@@ -56,8 +56,11 @@ typedef struct cairo_quartz_surface {
/* These are stored while drawing operations are in place, set up
* by quartz_setup_source() and quartz_finish_source()
*/
- CGAffineTransform imageTransform;
CGImageRef sourceImage;
+ cairo_surface_t *sourceImageSurface;
+ CGAffineTransform sourceImageTransform;
+ CGRect sourceImageRect;
+
CGShadingRef sourceShading;
CGPatternRef sourcePattern;
} cairo_quartz_surface_t;
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index dea8c26..dc831c1 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -472,28 +472,28 @@ _cairo_quartz_cairo_gradient_pattern_to_
/* generic cairo surface -> cairo_quartz_surface_t function */
static cairo_quartz_surface_t *
-_cairo_quartz_surface_to_quartz (cairo_surface_t *pat_surf)
+_cairo_quartz_surface_to_quartz (cairo_surface_t *target, cairo_surface_t *pat_surf)
{
cairo_quartz_surface_t *quartz_surf = NULL;
if (cairo_surface_get_type(pat_surf) != CAIRO_SURFACE_TYPE_QUARTZ) {
- /* This sucks; we should really store a dummy quartz surface
- * for passing in here
- * XXXtodo store a dummy quartz surface somewhere for handing off to clone_similar
- * XXXtodo/perf don't use clone if the source surface is an image surface! Instead,
+ /* XXXtodo/perf don't use clone if the source surface is an image surface! Instead,
* just create the CGImage directly!
*/
- cairo_surface_t *dummy = cairo_quartz_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+ cairo_surface_t *ref_type = target;
+ if (ref_type == NULL)
+ ref_type = cairo_quartz_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
cairo_surface_t *new_surf = NULL;
cairo_rectangle_int16_t rect;
_cairo_surface_get_extents (pat_surf, &rect);
- _cairo_surface_clone_similar (dummy, pat_surf, rect.x, rect.y,
+ _cairo_surface_clone_similar (ref_type, pat_surf, rect.x, rect.y,
rect.width, rect.height, &new_surf);
- cairo_surface_destroy(dummy);
+ if (target == NULL)
+ cairo_surface_destroy(ref_type);
quartz_surf = (cairo_quartz_surface_t *) new_surf;
} else {
@@ -515,7 +515,7 @@ SurfacePatternDrawFunc (void *info, CGCo
cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) info;
cairo_surface_t *pat_surf = spat->surface;
- cairo_quartz_surface_t *quartz_surf = _cairo_quartz_surface_to_quartz (pat_surf);
+ cairo_quartz_surface_t *quartz_surf = _cairo_quartz_surface_to_quartz (NULL, pat_surf);
CGImageRef img = CGBitmapContextCreateImage (quartz_surf->cgContext);
if (!img) {
@@ -685,7 +685,7 @@ typedef enum {
static cairo_quartz_action_t
_cairo_quartz_setup_source (cairo_quartz_surface_t *surface,
- cairo_pattern_t *source)
+ cairo_pattern_t *source)
{
assert (!(surface->sourceImage || surface->sourceShading || surface->sourcePattern));
@@ -714,13 +714,15 @@ _cairo_quartz_setup_source (cairo_quartz
surface->sourceShading = shading;
return DO_SHADING;
- } else if (source->type == CAIRO_PATTERN_TYPE_SURFACE
- && source->extend == CAIRO_EXTEND_NONE) {
+ } else if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
+ source->extend == CAIRO_EXTEND_NONE)
+ {
cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) source;
cairo_surface_t *pat_surf = spat->surface;
- cairo_quartz_surface_t *quartz_surf = _cairo_quartz_surface_to_quartz (pat_surf);
+ cairo_quartz_surface_t *quartz_surf = _cairo_quartz_surface_to_quartz (surface, pat_surf);
CGImageRef img = CGBitmapContextCreateImage (quartz_surf->cgContext);
cairo_matrix_t m = spat->base.matrix;
+ cairo_rectangle_int16_t extents;
if (!img)
return DO_UNSUPPORTED;
@@ -728,7 +730,13 @@ _cairo_quartz_setup_source (cairo_quartz
surface->sourceImage = img;
cairo_matrix_invert(&m);
- _cairo_quartz_cairo_matrix_to_quartz (&m, &surface->imageTransform);
+ _cairo_quartz_cairo_matrix_to_quartz (&m, &surface->sourceImageTransform);
+
+ _cairo_surface_get_extents (pat_surf, &extents);
+ surface->sourceImageRect = CGRectMake (0, 0, extents.width, extents.height);
+
+ surface->sourceImageSurface = (cairo_surface_t *)quartz_surf;
+
return DO_IMAGE;
} else if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
CGPatternRef pattern = _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (surface, source);
@@ -773,6 +781,9 @@ _cairo_quartz_teardown_source (cairo_qua
if (surface->sourceImage) {
CGImageRelease(surface->sourceImage);
surface->sourceImage = NULL;
+
+ cairo_surface_destroy(surface->sourceImageSurface);
+ surface->sourceImageSurface = NULL;
}
if (surface->sourceShading) {
@@ -1156,18 +1167,13 @@ _cairo_quartz_surface_paint (void *abstr
(cairo_surface_pattern_t *) source;
cairo_surface_t *pat_surf = surface_pattern->surface;
CGContextSaveGState (surface->cgContext);
- CGContextConcatCTM (surface->cgContext, surface->imageTransform);
+ CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform);
if (cairo_surface_get_type(pat_surf) == CAIRO_SURFACE_TYPE_QUARTZ) {
CGContextTranslateCTM (surface->cgContext, 0, CGImageGetHeight(surface->sourceImage));
CGContextScaleCTM (surface->cgContext, 1, -1);
}
- CGRect imageBounds;
- imageBounds.size = CGSizeMake (CGImageGetWidth(surface->sourceImage), CGImageGetHeight(surface->sourceImage));
- imageBounds.origin.x = 0;
- imageBounds.origin.y = 0;
-
- CGContextDrawImage (surface->cgContext, imageBounds, surface->sourceImage);
+ CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
CGContextRestoreGState (surface->cgContext);
} else {
rv = CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1238,18 +1244,13 @@ _cairo_quartz_surface_fill (void *abstra
CGContextClip (surface->cgContext);
else
CGContextEOClip (surface->cgContext);
- CGContextConcatCTM (surface->cgContext, surface->imageTransform);
+ CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform);
if (cairo_surface_get_type(pat_surf) == CAIRO_SURFACE_TYPE_QUARTZ) {
CGContextTranslateCTM (surface->cgContext, 0, CGImageGetHeight(surface->sourceImage));
CGContextScaleCTM (surface->cgContext, 1, -1);
}
- CGRect imageBounds;
- imageBounds.size = CGSizeMake (CGImageGetWidth(surface->sourceImage), CGImageGetHeight(surface->sourceImage));
- imageBounds.origin.x = 0;
- imageBounds.origin.y = 0;
-
- CGContextDrawImage (surface->cgContext, imageBounds, surface->sourceImage);
+ CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
} else {
rv = CAIRO_INT_STATUS_UNSUPPORTED;
}
@@ -1329,9 +1330,18 @@ _cairo_quartz_surface_stroke (void *abst
if (action == DO_SOLID || action == DO_PATTERN) {
CGContextStrokePath (surface->cgContext);
+ } else if (action == DO_IMAGE) {
+ CGContextReplacePathWithStrokedPath (surface->cgContext);
+ CGContextClip (surface->cgContext);
+
+ CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform);
+ if (cairo_surface_get_type(((cairo_surface_pattern_t*)source)->surface) == CAIRO_SURFACE_TYPE_QUARTZ) {
+ CGContextTranslateCTM (surface->cgContext, 0, CGImageGetHeight(surface->sourceImage));
+ CGContextScaleCTM (surface->cgContext, 1, -1);
+ }
+
+ CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
} else if (action == DO_SHADING) {
- // we have to clip and then paint the shading; first we have to convert
- // the stroke to a path that we can fill
CGContextReplacePathWithStrokedPath (surface->cgContext);
CGContextClip (surface->cgContext);
@@ -1376,7 +1386,7 @@ _cairo_quartz_surface_show_glyphs (void
action = _cairo_quartz_setup_source (surface, source);
if (action == DO_SOLID || action == DO_PATTERN) {
CGContextSetTextDrawingMode (surface->cgContext, kCGTextFill);
- } else if (action == DO_SHADING) {
+ } else if (action == DO_IMAGE || action == DO_SHADING) {
CGContextSetTextDrawingMode (surface->cgContext, kCGTextClip);
} else {
/* Unsupported */
@@ -1465,8 +1475,17 @@ _cairo_quartz_surface_show_glyphs (void
free (cg_advances);
}
- if (action == DO_SHADING)
+ if (action == DO_IMAGE) {
+ CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform);
+ if (cairo_surface_get_type(((cairo_surface_pattern_t*)source)->surface) == CAIRO_SURFACE_TYPE_QUARTZ) {
+ CGContextTranslateCTM (surface->cgContext, 0, CGImageGetHeight(surface->sourceImage));
+ CGContextScaleCTM (surface->cgContext, 1, -1);
+ }
+
+ CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
+ } else if (action == DO_SHADING) {
CGContextDrawShading (surface->cgContext, surface->sourceShading);
+ }
_cairo_quartz_teardown_source (surface, source);
diff-tree 39e6a0090faa4e73a658c1ca0ead3040309b84a2 (from 7c1afdcd597331c14f256f406a3e95743f7fdad6)
Author: Brian Ewins <Brian.Ewins at gmail.com>
Date: Fri Jun 8 01:12:24 2007 +0100
[quartz] fall back on extended gradients
A temporary fix for mozilla bug 379321, use an image fallback for
gradients that use EXTEND_REPEAT or EXTEND_REFLECT.
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index c2376fe..dea8c26 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -393,6 +393,13 @@ _cairo_quartz_cairo_gradient_pattern_to_
abspat->type != CAIRO_PATTERN_TYPE_RADIAL)
return NULL;
+ /* bandaid for mozilla bug 379321, also visible in the
+ * linear-gradient-reflect test.
+ */
+ if (abspat->extend == CAIRO_EXTEND_REFLECT ||
+ abspat->extend == CAIRO_EXTEND_REPEAT)
+ return NULL;
+
/* We can only do this if we have an identity pattern matrix;
* otherwise fall back through to the generic pattern case.
* XXXperf we could optimize this by creating a pattern with the shading;
diff-tree 7c1afdcd597331c14f256f406a3e95743f7fdad6 (from 55f1dbd0fbcbc587823ef8fa291a0af08441c775)
Author: Brian Ewins <Brian.Ewins at gmail.com>
Date: Mon Mar 26 00:06:23 2007 +0100
[quartz] fixes the offsets in the font-matrix test
Apply the font matrix offset to text on the quartz surface, if necessary.
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index e7bc519..c2376fe 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -1393,7 +1393,11 @@ _cairo_quartz_surface_show_glyphs (void
*/
//ND((stderr, "show_glyphs: glyph 0 at: %f, %f\n", glyphs[0].x, glyphs[0].y));
CGAffineTransform cairoTextTransform, textTransform, ctm;
- _cairo_quartz_cairo_matrix_to_quartz (&scaled_font->font_matrix, &cairoTextTransform);
+ cairoTextTransform = CGAffineTransformMake (scaled_font->font_matrix.xx,
+ scaled_font->font_matrix.yx,
+ scaled_font->font_matrix.xy,
+ scaled_font->font_matrix.yy,
+ 0., 0.);
textTransform = CGAffineTransformMakeTranslation (glyphs[0].x, glyphs[0].y);
textTransform = CGAffineTransformScale (textTransform, 1.0, -1.0);
diff-tree 55f1dbd0fbcbc587823ef8fa291a0af08441c775 (from 5a9de1b5c9f6cc445f9f6230937c2254ee49e7cb)
Author: Brian Ewins <Brian.Ewins at gmail.com>
Date: Sun Apr 1 00:04:24 2007 +0100
[quartz] ensure that line widths are scaled.
cairo-gstate applies the ctm to the coordinates used in paths,
but not to the line width. In quartz 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-quartz-surface.c b/src/cairo-quartz-surface.c
index 9da1bba..e7bc519 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -101,6 +101,11 @@ static void quartz_image_to_png (CGImage
* Cairo path -> Quartz path conversion helpers
*/
+typedef struct _quartz_stroke {
+ CGContextRef cgContext;
+ cairo_matrix_t *ctm_inverse;
+} quartz_stroke_t;
+
/* cairo path -> mutable path */
static cairo_status_t
_cairo_path_to_quartz_path_move_to (void *closure, cairo_point_t *point)
@@ -140,8 +145,14 @@ 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));
+ quartz_stroke_t *stroke = (quartz_stroke_t *)closure;
+ double x = _cairo_fixed_to_double (point->x);
+ double y = _cairo_fixed_to_double (point->y);
+
+ if (stroke->ctm_inverse)
+ cairo_matrix_transform_point (stroke->ctm_inverse, &x, &y);
+
+ CGContextMoveToPoint (stroke->cgContext, x, y);
return CAIRO_STATUS_SUCCESS;
}
@@ -149,12 +160,17 @@ 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));
+ quartz_stroke_t *stroke = (quartz_stroke_t *)closure;
+ double x = _cairo_fixed_to_double (point->x);
+ double y = _cairo_fixed_to_double (point->y);
+
+ if (stroke->ctm_inverse)
+ cairo_matrix_transform_point (stroke->ctm_inverse, &x, &y);
+
+ if (CGContextIsPathEmpty (stroke->cgContext))
+ CGContextMoveToPoint (stroke->cgContext, x, y);
else
- CGContextAddLineToPoint ((CGContextRef) closure,
- _cairo_fixed_to_double(point->x), _cairo_fixed_to_double(point->y));
+ CGContextAddLineToPoint (stroke->cgContext, x, y);
return CAIRO_STATUS_SUCCESS;
}
@@ -165,11 +181,22 @@ _cairo_path_to_quartz_context_curve_to (
// _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)));
+ quartz_stroke_t *stroke = (quartz_stroke_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);
+
+ if (stroke->ctm_inverse) {
+ cairo_matrix_transform_point (stroke->ctm_inverse, &x0, &y0);
+ cairo_matrix_transform_point (stroke->ctm_inverse, &x1, &y1);
+ cairo_matrix_transform_point (stroke->ctm_inverse, &x2, &y2);
+ }
- 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));
+ CGContextAddCurveToPoint (stroke->cgContext,
+ x0, y0, x1, y1, x2, y2);
return CAIRO_STATUS_SUCCESS;
}
@@ -177,7 +204,8 @@ static cairo_status_t
_cairo_path_to_quartz_context_close_path (void *closure)
{
//ND((stderr, "closepath\n"));
- CGContextClosePath ((CGContextRef) closure);
+ quartz_stroke_t *stroke = (quartz_stroke_t *)closure;
+ CGContextClosePath (stroke->cgContext);
return CAIRO_STATUS_SUCCESS;
}
@@ -1156,6 +1184,7 @@ _cairo_quartz_surface_fill (void *abstra
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
cairo_quartz_action_t action;
+ quartz_stroke_t stroke;
ND((stderr, "%p _cairo_quartz_surface_fill op %d source->type %d\n", surface, op, source->type));
@@ -1174,7 +1203,10 @@ _cairo_quartz_surface_fill (void *abstra
}
CGContextBeginPath (surface->cgContext);
- _cairo_quartz_cairo_path_to_quartz_context (path, surface->cgContext);
+
+ stroke.cgContext = surface->cgContext;
+ stroke.ctm_inverse = NULL;
+ _cairo_quartz_cairo_path_to_quartz_context (path, &stroke);
if (action == DO_SOLID || action == DO_PATTERN) {
if (fill_rule == CAIRO_FILL_RULE_WINDING)
@@ -1237,6 +1269,8 @@ _cairo_quartz_surface_stroke (void *abst
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
cairo_quartz_action_t action;
+ quartz_stroke_t stroke;
+ CGAffineTransform strokeTransform;
ND((stderr, "%p _cairo_quartz_surface_stroke op %d source->type %d\n", surface, op, source->type));
@@ -1252,6 +1286,8 @@ _cairo_quartz_surface_stroke (void *abst
CGContextSetLineCap (surface->cgContext, _cairo_quartz_cairo_line_cap_to_quartz (style->line_cap));
CGContextSetLineJoin (surface->cgContext, _cairo_quartz_cairo_line_join_to_quartz (style->line_join));
CGContextSetMiterLimit (surface->cgContext, style->miter_limit);
+ _cairo_quartz_cairo_matrix_to_quartz (ctm, &strokeTransform);
+ CGContextConcatCTM (surface->cgContext, strokeTransform);
if (style->dash && style->num_dashes) {
#define STATIC_DASH 32
@@ -1279,7 +1315,10 @@ _cairo_quartz_surface_stroke (void *abst
}
CGContextBeginPath (surface->cgContext);
- _cairo_quartz_cairo_path_to_quartz_context (path, surface->cgContext);
+
+ stroke.cgContext = surface->cgContext;
+ stroke.ctm_inverse = ctm_inverse;
+ _cairo_quartz_cairo_path_to_quartz_context (path, &stroke);
if (action == DO_SOLID || action == DO_PATTERN) {
CGContextStrokePath (surface->cgContext);
@@ -1472,6 +1511,7 @@ _cairo_quartz_surface_intersect_clip_pat
cairo_antialias_t antialias)
{
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
+ quartz_stroke_t stroke;
ND((stderr, "%p _cairo_quartz_surface_intersect_clip_path path: %p\n", surface, path));
@@ -1487,7 +1527,9 @@ _cairo_quartz_surface_intersect_clip_pat
CGContextSaveGState (surface->cgContext);
} else {
CGContextBeginPath (surface->cgContext);
- _cairo_quartz_cairo_path_to_quartz_context (path, surface->cgContext);
+ stroke.cgContext = surface->cgContext;
+ stroke.ctm_inverse = NULL;
+ _cairo_quartz_cairo_path_to_quartz_context (path, &stroke);
if (fill_rule == CAIRO_FILL_RULE_WINDING)
CGContextClip (surface->cgContext);
else
diff-tree 5a9de1b5c9f6cc445f9f6230937c2254ee49e7cb (from 807c5ab613e7df60be452d6683c4f9f045ef62a0)
Author: Brian Ewins <Brian.Ewins at gmail.com>
Date: Thu Jun 7 23:22:30 2007 +0100
[atsui] remove unused code
Remove CGAffineTransformMakeWithCairoFontScale.
diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c
index 599d525..34560d2 100644
--- a/src/cairo-atsui-font.c
+++ b/src/cairo-atsui-font.c
@@ -147,14 +147,6 @@ cairo_atsui_font_face_create_for_atsu_fo
return &font_face->base;
}
-static CGAffineTransform
-CGAffineTransformMakeWithCairoFontScale(const cairo_matrix_t *scale)
-{
- return CGAffineTransformMake(scale->xx, scale->yx,
- scale->xy, scale->yy,
- 0, 0);
-}
-
static ATSUStyle
CreateSizedCopyOfStyle(ATSUStyle inStyle,
const Fixed *theSize,
diff-tree 807c5ab613e7df60be452d6683c4f9f045ef62a0 (from b210b09e2de2f048debad6e8881f0226b6b17060)
Author: Brian Ewins <Brian.Ewins at gmail.com>
Date: Thu Jun 7 23:22:29 2007 +0100
[atsui] clean up warnings
Refactor code to get rid of compiler warnings.
diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c
index 5b39902..599d525 100644
--- a/src/cairo-atsui-font.c
+++ b/src/cairo-atsui-font.c
@@ -593,6 +593,7 @@ _cairo_atsui_scaled_font_init_glyph_surf
CGContextRef drawingContext;
cairo_image_surface_t *surface;
cairo_format_t format;
+ cairo_status_t status;
ATSFontRef atsFont;
CGFontRef cgFont;
@@ -609,8 +610,9 @@ _cairo_atsui_scaled_font_init_glyph_surf
if (theGlyph == kATSDeletedGlyphcode) {
surface = (cairo_image_surface_t *)cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2);
- if (cairo_surface_status (surface))
- return cairo_surface_status (surface);
+ status = cairo_surface_status ((cairo_surface_t *)surface);
+ if (status)
+ return status;
_cairo_scaled_glyph_set_surface (scaled_glyph,
&base,
@@ -676,8 +678,9 @@ _cairo_atsui_scaled_font_init_glyph_surf
/* create the glyph mask surface */
surface = (cairo_image_surface_t *)cairo_image_surface_create (format, bbox.size.width, bbox.size.height);
- if (cairo_surface_status (surface))
- return cairo_surface_status (surface);
+ status = cairo_surface_status ((cairo_surface_t *)surface);
+ if (status)
+ return status;
/* Create a CGBitmapContext for the dest surface for drawing into */
{
diff-tree b210b09e2de2f048debad6e8881f0226b6b17060 (from fa5dd548b0dd2dfe523501bd40cafe7916240be1)
Author: Brian Ewins <Brian.Ewins at gmail.com>
Date: Thu Jun 7 23:22:27 2007 +0100
[quartz] implement CAIRO_EXTEND_REFLECT
Implement extend-reflect by tiling a larger 2x2 grid of reflected
images.
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 748db62..9da1bba 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -506,6 +506,18 @@ SurfacePatternDrawFunc (void *info, CGCo
imageBounds.origin.y = 0;
CGContextDrawImage (context, imageBounds, img);
+ if (spat->base.extend == CAIRO_EXTEND_REFLECT) {
+ /* draw 3 more copies of the image, flipped. */
+ CGContextTranslateCTM (context, 0, 2 * imageBounds.size.height);
+ CGContextScaleCTM (context, 1, -1);
+ CGContextDrawImage (context, imageBounds, img);
+ CGContextTranslateCTM (context, 2 * imageBounds.size.width, 0);
+ CGContextScaleCTM (context, -1, 1);
+ CGContextDrawImage (context, imageBounds, img);
+ CGContextTranslateCTM (context, 0, 2 * imageBounds.size.height);
+ CGContextScaleCTM (context, 1, -1);
+ CGContextDrawImage (context, imageBounds, img);
+ }
CGImageRelease (img);
@@ -569,8 +581,24 @@ _cairo_quartz_cairo_repeating_surface_pa
_cairo_surface_get_extents (pat_surf, &extents);
pbounds.origin.x = 0;
pbounds.origin.y = 0;
- pbounds.size.width = extents.width;
- pbounds.size.height = extents.height;
+
+ // kjs seems to indicate this should work (setting to 0,0 to avoid
+ // tiling); however, the pattern CTM scaling ends up being NaN in
+ // the pattern draw function if either rw or rh are 0.
+ // XXXtodo get pattern drawing working with extend options
+ // XXXtodo/perf optimize CAIRO_EXTEND_NONE to a single DrawImage instead of a pattern
+ if (spat->base.extend == CAIRO_EXTEND_REFLECT) {
+ /* XXX broken; need to emulate by reflecting the image into 4 quadrants
+ * and then tiling that
+ */
+ pbounds.size.width = 2 * extents.width;
+ pbounds.size.height = 2 * extents.height;
+ } else {
+ pbounds.size.width = extents.width;
+ pbounds.size.height = extents.height;
+ }
+ rw = pbounds.size.width;
+ rh = pbounds.size.height;
m = spat->base.matrix;
cairo_matrix_invert(&m);
@@ -590,38 +618,6 @@ _cairo_quartz_cairo_repeating_surface_pa
ND((stderr, " context xform: t: %f %f xx: %f xy: %f yx: %f yy: %f\n", xform.tx, xform.ty, xform.a, xform.b, xform.c, xform.d));
#endif
- // kjs seems to indicate this should work (setting to 0,0 to avoid
- // tiling); however, the pattern CTM scaling ends up being NaN in
- // the pattern draw function if either rw or rh are 0.
- // XXXtodo get pattern drawing working with extend options
- // XXXtodo/perf optimize CAIRO_EXTEND_NONE to a single DrawImage instead of a pattern
-#if 0
- if (spat->base.extend == CAIRO_EXTEND_NONE) {
- /* XXX wasteful; this will keep drawing the pattern in the
- * original location. We need to set up the clip region
- * instead to do this right.
- */
- rw = 0;
- rh = 0;
- } else if (spat->base.extend == CAIRO_EXTEND_REPEAT) {
- rw = extents.width;
- rh = extents.height;
- } else if (spat->base.extend == CAIRO_EXTEND_REFLECT) {
- /* XXX broken; need to emulate by reflecting the image into 4 quadrants
- * and then tiling that
- */
- rw = extents.width;
- rh = extents.height;
- } else {
- /* CAIRO_EXTEND_PAD */
- /* XXX broken. */
- rw = 0;
- rh = 0;
- }
-#else
- rw = extents.width;
- rh = extents.height;
-#endif
/* XXX fixme: only do snapshots if the context is for printing, or get rid of the
other block if it doesn't fafect performance */
diff-tree fa5dd548b0dd2dfe523501bd40cafe7916240be1 (from 147288864c8c512f3ae17c8117d3c36dbbc6d5f8)
Author: Brian Ewins <Brian.Ewins at gmail.com>
Date: Tue May 29 23:11:49 2007 +0100
[quartz] implement CAIRO_EXTEND_NONE
Implement extend-none for surface patterns, by using a single
DrawImage where possible. There is some code duplication in this
patch, to make it easier to edit this patch series without conflicts.
A patch to remove duplicate code will be required later..
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 64a871d..748db62 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -648,6 +648,7 @@ typedef enum {
DO_SOLID,
DO_SHADING,
DO_PATTERN,
+ DO_IMAGE,
DO_UNSUPPORTED
} cairo_quartz_action_t;
@@ -682,6 +683,22 @@ _cairo_quartz_setup_source (cairo_quartz
surface->sourceShading = shading;
return DO_SHADING;
+ } else if (source->type == CAIRO_PATTERN_TYPE_SURFACE
+ && source->extend == CAIRO_EXTEND_NONE) {
+ cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) source;
+ cairo_surface_t *pat_surf = spat->surface;
+ cairo_quartz_surface_t *quartz_surf = _cairo_quartz_surface_to_quartz (pat_surf);
+ CGImageRef img = CGBitmapContextCreateImage (quartz_surf->cgContext);
+ cairo_matrix_t m = spat->base.matrix;
+
+ if (!img)
+ return DO_UNSUPPORTED;
+
+ surface->sourceImage = img;
+
+ cairo_matrix_invert(&m);
+ _cairo_quartz_cairo_matrix_to_quartz (&m, &surface->imageTransform);
+ return DO_IMAGE;
} else if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
CGPatternRef pattern = _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (surface, source);
if (!pattern)
@@ -694,7 +711,8 @@ _cairo_quartz_setup_source (cairo_quartz
// pattern (which may be stack allocated)
CGContextSaveGState(surface->cgContext);
- CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);
+ CGColorSpaceRef patternSpace;
+ patternSpace = CGColorSpaceCreatePattern(NULL);
CGContextSetFillColorSpace (surface->cgContext, patternSpace);
CGContextSetFillPattern (surface->cgContext, pattern, &patternAlpha);
CGContextSetStrokeColorSpace (surface->cgContext, patternSpace);
@@ -722,7 +740,8 @@ _cairo_quartz_teardown_source (cairo_qua
cairo_pattern_t *source)
{
if (surface->sourceImage) {
- // nothing to do; we don't use sourceImage yet
+ CGImageRelease(surface->sourceImage);
+ surface->sourceImage = NULL;
}
if (surface->sourceShading) {
@@ -1101,6 +1120,24 @@ _cairo_quartz_surface_paint (void *abstr
surface->extents.height));
} else if (action == DO_SHADING) {
CGContextDrawShading (surface->cgContext, surface->sourceShading);
+ } else if (action == DO_IMAGE) {
+ cairo_surface_pattern_t *surface_pattern =
+ (cairo_surface_pattern_t *) source;
+ cairo_surface_t *pat_surf = surface_pattern->surface;
+ CGContextSaveGState (surface->cgContext);
+ CGContextConcatCTM (surface->cgContext, surface->imageTransform);
+ if (cairo_surface_get_type(pat_surf) == CAIRO_SURFACE_TYPE_QUARTZ) {
+ CGContextTranslateCTM (surface->cgContext, 0, CGImageGetHeight(surface->sourceImage));
+ CGContextScaleCTM (surface->cgContext, 1, -1);
+ }
+
+ CGRect imageBounds;
+ imageBounds.size = CGSizeMake (CGImageGetWidth(surface->sourceImage), CGImageGetHeight(surface->sourceImage));
+ imageBounds.origin.x = 0;
+ imageBounds.origin.y = 0;
+
+ CGContextDrawImage (surface->cgContext, imageBounds, surface->sourceImage);
+ CGContextRestoreGState (surface->cgContext);
} else {
rv = CAIRO_INT_STATUS_UNSUPPORTED;
}
@@ -1158,6 +1195,26 @@ _cairo_quartz_surface_fill (void *abstra
CGContextEOClip (surface->cgContext);
CGContextDrawShading (surface->cgContext, surface->sourceShading);
+ } else if (action == DO_IMAGE) {
+ cairo_surface_pattern_t *surface_pattern =
+ (cairo_surface_pattern_t *) source;
+ cairo_surface_t *pat_surf = surface_pattern->surface;
+ if (fill_rule == CAIRO_FILL_RULE_WINDING)
+ CGContextClip (surface->cgContext);
+ else
+ CGContextEOClip (surface->cgContext);
+ CGContextConcatCTM (surface->cgContext, surface->imageTransform);
+ if (cairo_surface_get_type(pat_surf) == CAIRO_SURFACE_TYPE_QUARTZ) {
+ CGContextTranslateCTM (surface->cgContext, 0, CGImageGetHeight(surface->sourceImage));
+ CGContextScaleCTM (surface->cgContext, 1, -1);
+ }
+
+ CGRect imageBounds;
+ imageBounds.size = CGSizeMake (CGImageGetWidth(surface->sourceImage), CGImageGetHeight(surface->sourceImage));
+ imageBounds.origin.x = 0;
+ imageBounds.origin.y = 0;
+
+ CGContextDrawImage (surface->cgContext, imageBounds, surface->sourceImage);
} else {
rv = CAIRO_INT_STATUS_UNSUPPORTED;
}
diff-tree 147288864c8c512f3ae17c8117d3c36dbbc6d5f8 (from a5ee983e1cb97aff63b0c9c3a57125b37d0e3f74)
Author: Brian Ewins <Brian.Ewins at gmail.com>
Date: Thu Jun 7 23:22:05 2007 +0100
[quartz] Refactor code to create a CGImageRef from a pattern
In order to implement CAIRO_EXTEND_NONE we will need to create
a CGImageRef without also creating a CGPattern. Separate the two
pieces of code.
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 3a80908..64a871d 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -435,20 +435,12 @@ _cairo_quartz_cairo_gradient_pattern_to_
return NULL;
}
-
-/* Generic cairo_pattern -> CGPattern function */
-static void
-SurfacePatternDrawFunc (void *info, CGContextRef context)
+/* generic cairo surface -> cairo_quartz_surface_t function */
+static cairo_quartz_surface_t *
+_cairo_quartz_surface_to_quartz (cairo_surface_t *pat_surf)
{
- cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) info;
- cairo_surface_t *pat_surf = spat->surface;
-
cairo_quartz_surface_t *quartz_surf = NULL;
- cairo_bool_t flip = FALSE;
-
- CGImageRef img;
-
if (cairo_surface_get_type(pat_surf) != CAIRO_SURFACE_TYPE_QUARTZ) {
/* This sucks; we should really store a dummy quartz surface
* for passing in here
@@ -476,15 +468,20 @@ SurfacePatternDrawFunc (void *info, CGCo
cairo_surface_reference (pat_surf);
quartz_surf = (cairo_quartz_surface_t*) pat_surf;
- /* XXXtodo WHY does this need to be flipped? Writing this stuff
- * to disk shows that in both this path and the path above the source image
- * has an identical orientation, and the destination context at all times has a Y
- * flip. So why do we need to flip in this case?
- */
- flip = TRUE;
}
- img = CGBitmapContextCreateImage (quartz_surf->cgContext);
+ return quartz_surf;
+}
+
+/* Generic cairo_pattern -> CGPattern function */
+static void
+SurfacePatternDrawFunc (void *info, CGContextRef context)
+{
+ cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) info;
+ cairo_surface_t *pat_surf = spat->surface;
+
+ cairo_quartz_surface_t *quartz_surf = _cairo_quartz_surface_to_quartz (pat_surf);
+ CGImageRef img = CGBitmapContextCreateImage (quartz_surf->cgContext);
if (!img) {
// ... give up.
@@ -493,7 +490,12 @@ SurfacePatternDrawFunc (void *info, CGCo
return;
}
- if (flip) {
+ /* XXXtodo WHY does this need to be flipped? Writing this stuff
+ * to disk shows that in both this path and the path above the source image
+ * has an identical orientation, and the destination context at all times has a Y
+ * flip. So why do we need to flip in this case?
+ */
+ if (cairo_surface_get_type(pat_surf) == CAIRO_SURFACE_TYPE_QUARTZ) {
CGContextTranslateCTM (context, 0, CGImageGetHeight(img));
CGContextScaleCTM (context, 1, -1);
}
More information about the cairo-commit
mailing list