[cairo-commit] 13 commits - doc/tutorial src/cairo-analysis-surface.c src/cairo-clip.c src/cairo-image-surface.c src/cairoint.h src/cairo-meta-surface.c src/cairo-paginated-surface.c src/cairo-path-bounds.c src/cairo-pattern.c src/cairo-pdf-surface.c src/cairo-rectangle.c src/cairo-scaled-font.c src/cairo-script-surface.c src/cairo-surface.c src/cairo-surface-fallback.c src/cairo-svg-surface.c src/cairo-type3-glyph-surface.c src/cairo-xlib-surface.c src/test-meta-surface.c src/test-paginated-surface.c test/twin.c test/twin.pdf.ref.png test/twin.ref.png util/cairo-script util/cairo-trace
Chris Wilson
ickle at kemper.freedesktop.org
Thu Dec 18 04:12:50 PST 2008
doc/tutorial/src/twin.c | 2
src/cairo-analysis-surface.c | 60 ++++++------------
src/cairo-clip.c | 25 ++++---
src/cairo-image-surface.c | 42 +++++++-----
src/cairo-meta-surface.c | 1
src/cairo-paginated-surface.c | 1
src/cairo-path-bounds.c | 95 ++++++++++++++---------------
src/cairo-pattern.c | 54 +++++++++++-----
src/cairo-pdf-surface.c | 1
src/cairo-rectangle.c | 10 +++
src/cairo-scaled-font.c | 44 +++++++------
src/cairo-script-surface.c | 1
src/cairo-surface-fallback.c | 9 +-
src/cairo-surface.c | 41 +++++++-----
src/cairo-svg-surface.c | 18 ++---
src/cairo-type3-glyph-surface.c | 20 +-----
src/cairo-xlib-surface.c | 12 +++
src/cairoint.h | 20 ++++--
src/test-meta-surface.c | 1
src/test-paginated-surface.c | 1
test/twin.c | 2
test/twin.pdf.ref.png |binary
test/twin.ref.png |binary
util/cairo-script/cairo-script-operators.c | 54 ++++++----------
util/cairo-script/csi-replay.c | 6 +
util/cairo-trace/trace.c | 47 +++++++-------
26 files changed, 303 insertions(+), 264 deletions(-)
New commits:
commit dea40e61babe608315b6d365094cf518814b134e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 18 11:50:00 2008 +0000
[path] Return the fixed-point bounds of the path
When analysing the stroke extents, we need the original fixed-point
extents so that we do not incur an OBO when we round-to-integer a second
time. We also need a more accurate estimate than simply using the control
points of the curve, so pass in tolerance and decompose until someone
discovers a cheaper algorithm to determine the precise aligned bounding
box of a bezier curve.
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index e098445..b8f2ab4 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -290,11 +290,12 @@ _cairo_analysis_surface_intersect_clip_path (void *abstract_surface,
surface->current_clip.width = surface->width;
surface->current_clip.height = surface->height;
} else {
- cairo_rectangle_int_t extent;
+ cairo_box_t extents;
cairo_bool_t is_empty;
- _cairo_path_fixed_approximate_extents (path, &extent);
- is_empty = _cairo_rectangle_intersect (&surface->current_clip, &extent);
+ _cairo_path_fixed_approximate_extents (path, tolerance, &extents);
+ is_empty = _cairo_rectangle_intersect_box (&surface->current_clip,
+ &extents);
}
return CAIRO_STATUS_SUCCESS;
@@ -477,22 +478,19 @@ _cairo_analysis_surface_stroke (void *abstract_surface,
is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
if (_cairo_operator_bounded_by_mask (op)) {
- cairo_rectangle_int_t mask_extents;
+ cairo_box_t mask_extents;
double dx, dy;
- _cairo_path_fixed_approximate_extents (path, &mask_extents);
+ _cairo_path_fixed_approximate_extents (path, tolerance, &mask_extents);
_cairo_stroke_style_max_distance_from_path (style, ctm, &dx, &dy);
- mask_extents.width += mask_extents.x + ceil (dx);
- mask_extents.x -= ceil (dx);
- mask_extents.width -= mask_extents.x;
-
- mask_extents.height += mask_extents.y + ceil (dy);
- mask_extents.y -= ceil (dy);
- mask_extents.height -= mask_extents.y;
+ mask_extents.p1.x -= _cairo_fixed_from_double (dx);
+ mask_extents.p2.x += _cairo_fixed_from_double (dx);
+ mask_extents.p1.y -= _cairo_fixed_from_double (dy);
+ mask_extents.p2.y += _cairo_fixed_from_double (dy);
- is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
+ is_empty = _cairo_rectangle_intersect_box (&extents, &mask_extents);
}
if (stroke_extents)
*stroke_extents = extents;
@@ -544,11 +542,11 @@ _cairo_analysis_surface_fill (void *abstract_surface,
is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
if (_cairo_operator_bounded_by_mask (op)) {
- cairo_rectangle_int_t mask_extents;
+ cairo_box_t mask_extents;
- _cairo_path_fixed_approximate_extents (path, &mask_extents);
+ _cairo_path_fixed_approximate_extents (path, tolerance, &mask_extents);
- is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
+ is_empty = _cairo_rectangle_intersect_box (&extents, &mask_extents);
}
if (fill_extents)
*fill_extents = extents;
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index c679e9f..cd36924 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -143,11 +143,13 @@ _cairo_clip_path_intersect_to_rectangle (cairo_clip_path_t *clip_path,
cairo_rectangle_int_t *rectangle)
{
while (clip_path) {
- cairo_rectangle_int_t extents;
+ cairo_box_t extents;
- _cairo_path_fixed_approximate_extents (&clip_path->path, &extents);
+ _cairo_path_fixed_approximate_extents (&clip_path->path,
+ clip_path->tolerance,
+ &extents);
- if (! _cairo_rectangle_intersect (rectangle, &extents))
+ if (! _cairo_rectangle_intersect_box (rectangle, &extents))
return CAIRO_STATUS_SUCCESS;
clip_path = clip_path->prev;
@@ -568,20 +570,21 @@ _cairo_clip_intersect_mask_using_spans (cairo_clip_t *clip,
goto BAIL;
}
+ status = _cairo_surface_get_extents (target, &surface_rect);
+ if (status)
+ goto BAIL;
+
/* We'll create a new surface the size of the intersection of the
* old mask surface and the extents of the new clip path. */
{
- cairo_rectangle_int_t target_rect;
+ cairo_box_t extents;
- _cairo_path_fixed_approximate_extents (path, &surface_rect);
-
- if (clip->surface != NULL &&
- !_cairo_rectangle_intersect (&surface_rect, &clip->surface_rect))
+ _cairo_path_fixed_approximate_extents (path, tolerance, &extents);
+ if (! _cairo_rectangle_intersect_box (&surface_rect, &extents))
goto SUCCESS;
- status = _cairo_surface_get_extents (target, &target_rect);
- if (status != CAIRO_STATUS_SUCCESS &&
- !_cairo_rectangle_intersect (&surface_rect, &target_rect))
+ if (clip->surface != NULL &&
+ ! _cairo_rectangle_intersect (&surface_rect, &clip->surface_rect))
goto SUCCESS;
}
diff --git a/src/cairo-path-bounds.c b/src/cairo-path-bounds.c
index b7411d2..25737e8 100644
--- a/src/cairo-path-bounds.c
+++ b/src/cairo-path-bounds.c
@@ -37,19 +37,19 @@
#include "cairoint.h"
typedef struct cairo_path_bounder {
+ double tolerance;
+
cairo_point_t move_to_point;
cairo_bool_t has_move_to_point;
cairo_bool_t has_point;
- cairo_fixed_t min_x;
- cairo_fixed_t min_y;
- cairo_fixed_t max_x;
- cairo_fixed_t max_y;
+ cairo_box_t extents;
} cairo_path_bounder_t;
static void
-_cairo_path_bounder_init (cairo_path_bounder_t *bounder)
+_cairo_path_bounder_init (cairo_path_bounder_t *bounder, double tolerance)
{
+ bounder->tolerance = tolerance;
bounder->has_move_to_point = FALSE;
bounder->has_point = FALSE;
}
@@ -66,22 +66,22 @@ _cairo_path_bounder_add_point (cairo_path_bounder_t *bounder,
const cairo_point_t *point)
{
if (bounder->has_point) {
- if (point->x < bounder->min_x)
- bounder->min_x = point->x;
+ if (point->x < bounder->extents.p1.x)
+ bounder->extents.p1.x = point->x;
- if (point->y < bounder->min_y)
- bounder->min_y = point->y;
+ if (point->y < bounder->extents.p1.y)
+ bounder->extents.p1.y = point->y;
- if (point->x > bounder->max_x)
- bounder->max_x = point->x;
+ if (point->x > bounder->extents.p2.x)
+ bounder->extents.p2.x = point->x;
- if (point->y > bounder->max_y)
- bounder->max_y = point->y;
+ if (point->y > bounder->extents.p2.y)
+ bounder->extents.p2.y = point->y;
} else {
- bounder->min_x = point->x;
- bounder->min_y = point->y;
- bounder->max_x = point->x;
- bounder->max_y = point->y;
+ bounder->extents.p1.x = point->x;
+ bounder->extents.p1.y = point->y;
+ bounder->extents.p2.x = point->x;
+ bounder->extents.p2.y = point->y;
bounder->has_point = TRUE;
}
@@ -123,18 +123,21 @@ _cairo_path_bounder_curve_to (void *closure,
const cairo_point_t *d)
{
cairo_path_bounder_t *bounder = closure;
-
- if (bounder->has_move_to_point) {
- _cairo_path_bounder_add_point (bounder,
- &bounder->move_to_point);
- bounder->has_move_to_point = FALSE;
+ cairo_spline_t spline;
+
+ /* XXX Is there a faster way to determine the bounding box of a
+ * Bezier curve than its decomposition?
+ *
+ * Using the control points alone can be wildly inaccurate.
+ */
+ if (! _cairo_spline_init (&spline,
+ _cairo_path_bounder_line_to, bounder,
+ &bounder->move_to_point, b, c, d))
+ {
+ return _cairo_path_bounder_line_to (bounder, d);
}
- _cairo_path_bounder_add_point (bounder, b);
- _cairo_path_bounder_add_point (bounder, c);
- _cairo_path_bounder_add_point (bounder, d);
-
- return CAIRO_STATUS_SUCCESS;
+ return _cairo_spline_decompose (&spline, bounder->tolerance);
}
static cairo_status_t
@@ -149,12 +152,13 @@ _cairo_path_bounder_close_path (void *closure)
*/
void
_cairo_path_fixed_approximate_extents (cairo_path_fixed_t *path,
- cairo_rectangle_int_t *extents)
+ double tolerance,
+ cairo_box_t *extents)
{
cairo_path_bounder_t bounder;
cairo_status_t status;
- _cairo_path_bounder_init (&bounder);
+ _cairo_path_bounder_init (&bounder, tolerance);
status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD,
_cairo_path_bounder_move_to,
@@ -165,15 +169,10 @@ _cairo_path_fixed_approximate_extents (cairo_path_fixed_t *path,
assert (status == CAIRO_STATUS_SUCCESS);
if (bounder.has_point) {
- extents->x = _cairo_fixed_integer_floor (bounder.min_x);
- extents->y = _cairo_fixed_integer_floor (bounder.min_y);
- extents->width =
- _cairo_fixed_integer_ceil (bounder.max_x) - extents->x;
- extents->height =
- _cairo_fixed_integer_ceil (bounder.max_y) - extents->y;
+ *extents = bounder.extents;
} else {
- extents->x = extents->y = 0;
- extents->width = extents->height = 0;
+ extents->p1.x = extents->p1.y = 0;
+ extents->p2.x = extents->p2.y = 0;
}
_cairo_path_bounder_fini (&bounder);
@@ -188,21 +187,21 @@ _cairo_path_fixed_bounds (cairo_path_fixed_t *path,
cairo_path_bounder_t bounder;
cairo_status_t status;
- _cairo_path_bounder_init (&bounder);
+ _cairo_path_bounder_init (&bounder, tolerance);
- status = _cairo_path_fixed_interpret_flat (path, CAIRO_DIRECTION_FORWARD,
- _cairo_path_bounder_move_to,
- _cairo_path_bounder_line_to,
- _cairo_path_bounder_close_path,
- &bounder,
- tolerance);
+ status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD,
+ _cairo_path_bounder_move_to,
+ _cairo_path_bounder_line_to,
+ _cairo_path_bounder_curve_to,
+ _cairo_path_bounder_close_path,
+ &bounder);
assert (status == CAIRO_STATUS_SUCCESS);
if (bounder.has_point) {
- *x1 = _cairo_fixed_to_double (bounder.min_x);
- *y1 = _cairo_fixed_to_double (bounder.min_y);
- *x2 = _cairo_fixed_to_double (bounder.max_x);
- *y2 = _cairo_fixed_to_double (bounder.max_y);
+ *x1 = _cairo_fixed_to_double (bounder.extents.p1.x);
+ *y1 = _cairo_fixed_to_double (bounder.extents.p1.y);
+ *x2 = _cairo_fixed_to_double (bounder.extents.p2.x);
+ *y2 = _cairo_fixed_to_double (bounder.extents.p2.y);
} else {
*x1 = 0.0;
*y1 = 0.0;
diff --git a/src/cairo-rectangle.c b/src/cairo-rectangle.c
index b139624..31a530e 100644
--- a/src/cairo-rectangle.c
+++ b/src/cairo-rectangle.c
@@ -126,6 +126,16 @@ _cairo_rectangle_intersect (cairo_rectangle_int_t *dst,
}
}
+cairo_bool_t
+_cairo_rectangle_intersect_box (cairo_rectangle_int_t *dst,
+ const cairo_box_t *src)
+{
+ cairo_rectangle_int_t rect;
+
+ _cairo_box_round_to_rectangle (src, &rect);
+ return _cairo_rectangle_intersect (dst, &rect);
+}
+
#define P1x (line->p1.x)
#define P1y (line->p1.y)
#define P2x (line->p2.x)
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index b48435d..0fd1dee 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -955,9 +955,12 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface,
info.antialias = antialias;
if (_cairo_operator_bounded_by_mask (op)) {
- cairo_rectangle_int_t path_extents;
- _cairo_path_fixed_approximate_extents (path, &path_extents);
- if (! _cairo_rectangle_intersect (&extents, &path_extents))
+ cairo_box_t path_extents;
+
+ _cairo_path_fixed_approximate_extents (path,
+ tolerance,
+ &path_extents);
+ if (! _cairo_rectangle_intersect_box (&extents, &path_extents))
return CAIRO_STATUS_SUCCESS;
}
diff --git a/src/cairoint.h b/src/cairoint.h
index 8166436..88945a3 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -259,6 +259,10 @@ _cairo_rectangle_intersect (cairo_rectangle_int_t *dst,
const cairo_rectangle_int_t *src);
cairo_private cairo_bool_t
+_cairo_rectangle_intersect_box (cairo_rectangle_int_t *dst,
+ const cairo_box_t *src);
+
+cairo_private cairo_bool_t
_cairo_box_intersects_line_segment (cairo_box_t *box, cairo_line_t *line);
cairo_private cairo_bool_t
@@ -1540,8 +1544,9 @@ _cairo_path_fixed_append (cairo_path_fixed_t *path,
cairo_direction_t dir);
cairo_private void
-_cairo_path_fixed_approximate_extents (cairo_path_fixed_t *path,
- cairo_rectangle_int_t *extents);
+_cairo_path_fixed_approximate_extents (cairo_path_fixed_t *path,
+ double tolerance,
+ cairo_box_t *extents);
cairo_private void
_cairo_path_fixed_bounds (cairo_path_fixed_t *path,
commit 3a53e0261b1b5af21bf37e2a211eefd501bd5358
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 18 11:10:17 2008 +0000
[test] Update twin reference images.
Closing the 'o' in twin has removed a slight artefact - update the reference
images to match.
diff --git a/test/twin.pdf.ref.png b/test/twin.pdf.ref.png
index b9121e0..366ad9a 100644
Binary files a/test/twin.pdf.ref.png and b/test/twin.pdf.ref.png differ
diff --git a/test/twin.ref.png b/test/twin.ref.png
index 29c2e9e..5c1cf2d 100644
Binary files a/test/twin.ref.png and b/test/twin.ref.png differ
commit c2478de26cc1781b8f8604191a9f75ad29eac746
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 18 10:50:45 2008 +0000
[twin] Switch internal users to the new name.
s/<cairo>/@cairo:/
diff --git a/doc/tutorial/src/twin.c b/doc/tutorial/src/twin.c
index e167f26..14347ba 100644
--- a/doc/tutorial/src/twin.c
+++ b/doc/tutorial/src/twin.c
@@ -20,7 +20,7 @@ draw (cairo_t *cr, int width, int height)
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_select_font_face (cr,
- "<cairo>",
+ "@cairo:",
CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_NORMAL);
diff --git a/test/twin.c b/test/twin.c
index a53b796..b04caf5 100644
--- a/test/twin.c
+++ b/test/twin.c
@@ -33,7 +33,7 @@ draw (cairo_t *cr, int width, int height)
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_select_font_face (cr,
- "<cairo>",
+ "@cairo:",
CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (cr, 16);
commit 3424b5f8c8cb1f2ef16b9e8429e64f720106f4d8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 18 10:47:44 2008 +0000
[scaled-font] Make check-doc happy
Replace a structure marker '#' with a macro marker '%'.
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 52b6fa5..8ffbcb4 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -248,7 +248,7 @@ _cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font,
*
* This function returns the type of the backend used to create
* a scaled font. See #cairo_font_type_t for available types.
- * However, this function never returns #CAIRO_FONT_TYPE_TOY.
+ * However, this function never returns %CAIRO_FONT_TYPE_TOY.
*
* Return value: The type of @scaled_font.
*
@@ -2466,7 +2466,7 @@ _cairo_scaled_font_get_max_scale (cairo_scaled_font_t *scaled_font)
*
* Gets the font face that this scaled font uses. This is the
* font face passed to cairo_scaled_font_create() if that font face
- * was not of type #CAIRO_FONT_TYPE_TOY.
+ * was not of type %CAIRO_FONT_TYPE_TOY.
*
* Return value: The #cairo_font_face_t with which @scaled_font was
* created.
commit 449bf0bb7bff38da1c5d0286cb4f22c858bcc3a9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 18 10:45:22 2008 +0000
[script] Silence incorrect compiler warnings
Bah, the compiler failed to do its IPA correctly and wrongly complained
about potential use of uninitialised out-params guarded by the return
value. Silence them!
diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c
index 28e449e..935ca7f 100644
--- a/util/cairo-script/cairo-script-operators.c
+++ b/util/cairo-script/cairo-script-operators.c
@@ -692,7 +692,7 @@ _add_color_stop (csi_t *ctx)
{
csi_status_t status;
double offset, r, g, b, a;
- cairo_pattern_t *pattern;
+ cairo_pattern_t *pattern = NULL; /* silence the compiler */
check (6);
@@ -1103,7 +1103,7 @@ _curve_to (csi_t *ctx)
static csi_status_t
_def (csi_t *ctx)
{
- csi_name_t name;
+ csi_name_t name = 0; /* silence the compiler */
csi_status_t status;
check (2);
@@ -1246,7 +1246,7 @@ _filter (csi_t *ctx)
csi_object_t *src;
csi_dictionary_t *dict = NULL;
csi_status_t status;
- const char *name;
+ const char *name = NULL; /* silence the compiler */
const struct filters {
const char *name;
csi_status_t (*constructor) (csi_t *t,
@@ -1771,7 +1771,7 @@ _font (csi_t *ctx)
{
csi_dictionary_t *font;
csi_status_t status;
- cairo_font_face_t *font_face;
+ cairo_font_face_t *font_face = NULL; /* silence the compiler */
csi_proxy_t *proxy;
csi_object_t obj;
long type;
@@ -2310,7 +2310,7 @@ static csi_status_t
_if (csi_t *ctx)
{
csi_array_t *proc;
- csi_boolean_t predicate;
+ csi_boolean_t predicate = FALSE; /* silence the compiler */
csi_status_t status;
check (2);
@@ -2339,7 +2339,7 @@ static csi_status_t
_ifelse (csi_t *ctx)
{
csi_array_t *true_proc, *false_proc;
- csi_boolean_t predicate;
+ csi_boolean_t predicate = FALSE; /* silence the compiler */
csi_status_t status;
check (3);
@@ -2654,7 +2654,7 @@ _image_load_from_dictionary (csi_t *ctx,
long width;
long height;
long format;
- cairo_surface_t *image;
+ cairo_surface_t *image = NULL; /* silence the compiler */
csi_status_t status;
/* check for "status? */
@@ -2989,9 +2989,9 @@ _null (csi_t *ctx)
static csi_status_t
_mask (csi_t *ctx)
{
- csi_status_t status;
cairo_t *cr;
- cairo_pattern_t *pattern;
+ cairo_pattern_t *pattern = NULL; /* silence the compiler */
+ csi_status_t status;
check (2);
@@ -3682,10 +3682,10 @@ _scaled_font (csi_t *ctx)
{
csi_object_t obj;
csi_dictionary_t *dict;
- csi_status_t status;
- cairo_font_face_t *font_face;
+ cairo_font_face_t *font_face = NULL; /* silence the compiler */
cairo_matrix_t font_matrix, ctm;
cairo_font_options_t *options;
+ csi_status_t status;
check (4);
@@ -4063,9 +4063,9 @@ _set_filter (csi_t *ctx)
static csi_status_t
_set_font_face (csi_t *ctx)
{
- csi_status_t status;
- cairo_font_face_t *font;
cairo_t *cr;
+ cairo_font_face_t *font = NULL; /* silence the compiler */
+ csi_status_t status;
check (2);
@@ -4264,7 +4264,7 @@ _set_mime_data (csi_t *ctx)
{
csi_status_t status;
csi_object_t *obj;
- const char *mime;
+ const char *mime = NULL; /* silence the compiler */
csi_object_t source;
cairo_surface_t *surface;
struct _mime_tag *tag;
@@ -4365,9 +4365,9 @@ _set_operator (csi_t *ctx)
static csi_status_t
_set_scaled_font (csi_t *ctx)
{
- csi_status_t status;
- cairo_scaled_font_t *font;
cairo_t *cr;
+ cairo_scaled_font_t *font = NULL; /* silence the compiler */
+ csi_status_t status;
check (2);
@@ -4387,7 +4387,7 @@ static csi_status_t
_set_source (csi_t *ctx)
{
cairo_t *cr;
- cairo_pattern_t *pattern;
+ cairo_pattern_t *pattern = NULL; /* silence the compiler */
csi_status_t status;
check (2);
@@ -5288,7 +5288,7 @@ _text_path (csi_t *ctx)
static csi_status_t
_undef (csi_t *ctx)
{
- csi_name_t name;
+ csi_name_t name = 0; /* silence the compiler */
csi_status_t status;
check (1);
@@ -5309,7 +5309,7 @@ static csi_status_t
_unset (csi_t *ctx)
{
csi_object_t *dst;
- csi_name_t name;
+ csi_name_t name = 0; /* silence the compiler */
csi_status_t status;
check (2);
commit ce0b136a441382b25d0932cd66a906a30a693365
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Dec 17 20:34:45 2008 +0000
Query the backend to see if we can repaint the solid pattern.
If we are dithering on the Xlib backend we can not simply repaint the
surface used for a solid pattern and must recreate it from scratch.
However, for ordinary XRender usage we do not want to have to pay that
price - so query the backend to see if we can reuse the surface.
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index 0529a74..e098445 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -749,6 +749,7 @@ static const cairo_surface_backend_t cairo_analysis_surface_backend = {
NULL, /* reset */
NULL, /* fill_stroke */
NULL, /* create_solid_pattern_surface */
+ NULL, /* can_repaint_solid_pattern_surface */
_cairo_analysis_surface_has_show_text_glyphs,
_cairo_analysis_surface_show_text_glyphs
};
@@ -966,6 +967,7 @@ static const cairo_surface_backend_t cairo_null_surface_backend = {
NULL, /* reset */
NULL, /* fill_stroke */
NULL, /* create_solid_pattern_surface */
+ NULL, /* can_repaint_solid_pattern_surface */
NULL, /* has_show_text_glyphs */
NULL /* show_text_glyphs */
};
diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c
index 0f6e632..6938526 100644
--- a/src/cairo-meta-surface.c
+++ b/src/cairo-meta-surface.c
@@ -678,6 +678,7 @@ static const cairo_surface_backend_t cairo_meta_surface_backend = {
NULL, /* reset */
NULL, /* fill_stroke */
NULL, /* create_solid_pattern_surface */
+ NULL, /* can_repaint_solid_pattern_surface */
_cairo_meta_surface_has_show_text_glyphs,
_cairo_meta_surface_show_text_glyphs
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index ce4e4de..5d4e08f 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -701,6 +701,7 @@ static const cairo_surface_backend_t cairo_paginated_surface_backend = {
NULL, /* reset */
NULL, /* fill_stroke */
NULL, /* create_solid_pattern_surface */
+ NULL, /* can_repaint_solid_pattern_surface */
_cairo_paginated_surface_has_show_text_glyphs,
_cairo_paginated_surface_show_text_glyphs
};
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 5862c4b..d453f20 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -5335,6 +5335,7 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend = {
NULL, /* reset */
_cairo_pdf_surface_fill_stroke,
NULL, /* create_solid_pattern_surface */
+ NULL, /* can_repaint_solid_pattern_surface */
_cairo_pdf_surface_has_show_text_glyphs,
_cairo_pdf_surface_show_text_glyphs,
};
diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c
index 906e4ed..2585a50 100644
--- a/src/cairo-script-surface.c
+++ b/src/cairo-script-surface.c
@@ -2452,6 +2452,7 @@ _cairo_script_surface_backend = {
NULL, /* reset */
NULL, /* fill_stroke */
NULL, /* create_solid_pattern_surface */
+ NULL, /* can_repaint_solid_pattern_surface */
/* The alternate high-level text operation */
_cairo_script_surface_has_show_text_glyphs,
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 077af5b..4dd034e 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -334,19 +334,19 @@ cairo_surface_t *
_cairo_surface_create_solid_pattern_surface (cairo_surface_t *other,
const cairo_solid_pattern_t *solid_pattern)
{
- cairo_surface_t *surface;
+ if (other->backend->create_solid_pattern_surface != NULL) {
+ cairo_surface_t *surface;
- if (other->backend->create_solid_pattern_surface) {
- surface = other->backend->create_solid_pattern_surface (other, solid_pattern);
+ surface = other->backend->create_solid_pattern_surface (other,
+ solid_pattern);
if (surface)
return surface;
}
- surface = _cairo_surface_create_similar_solid (other,
- solid_pattern->content,
- 1, 1,
- &solid_pattern->color);
- return surface;
+ return _cairo_surface_create_similar_solid (other,
+ solid_pattern->content,
+ 1, 1,
+ &solid_pattern->color);
}
cairo_int_status_t
@@ -354,17 +354,24 @@ _cairo_surface_repaint_solid_pattern_surface (cairo_surface_t *other,
cairo_surface_t *solid_surface,
const cairo_solid_pattern_t *solid_pattern)
{
- if (other->backend->create_solid_pattern_surface)
- /* Solid pattern surface for this backend are not trivial to make.
- * Skip repainting.
- *
- * This does not work optimally with things like analysis surface that
- * are proxies. But returning UNSUPPORTED is *safe* as it only
- * disables some caching.
- */
+ /* Solid pattern surface for these backends are special and not trivial
+ * to repaint. Skip repainting.
+ *
+ * This does not work optimally with things like analysis surface that
+ * are proxies. But returning UNSUPPORTED is *safe* as it only
+ * disables some caching.
+ */
+ if (other->backend->create_solid_pattern_surface != NULL &&
+ ! other->backend->can_repaint_solid_pattern_surface (solid_surface,
+ solid_pattern))
+ {
return CAIRO_INT_STATUS_UNSUPPORTED;
+ }
- return _cairo_surface_paint (solid_surface, CAIRO_OPERATOR_SOURCE, &solid_pattern->base, NULL);
+ return _cairo_surface_paint (solid_surface,
+ CAIRO_OPERATOR_SOURCE,
+ &solid_pattern->base,
+ NULL);
}
cairo_clip_mode_t
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 68d8192..1826ed9 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1310,6 +1310,15 @@ _cairo_xlib_surface_create_solid_pattern_surface (void *abstrac
return &surface->base;
}
+static cairo_bool_t
+_cairo_xlib_surface_can_repaint_solid_pattern_surface (void *abstract_surface,
+ const cairo_solid_pattern_t *solid_pattern)
+{
+ cairo_xlib_surface_t *other = abstract_surface;
+ return CAIRO_SURFACE_RENDER_HAS_COMPOSITE (other);
+}
+
+
static cairo_status_t
_cairo_xlib_surface_set_matrix (cairo_xlib_surface_t *surface,
cairo_matrix_t *matrix,
@@ -2469,7 +2478,8 @@ static const cairo_surface_backend_t cairo_xlib_surface_backend = {
_cairo_xlib_surface_is_similar,
_cairo_xlib_surface_reset,
NULL, /* fill_stroke */
- _cairo_xlib_surface_create_solid_pattern_surface
+ _cairo_xlib_surface_create_solid_pattern_surface,
+ _cairo_xlib_surface_can_repaint_solid_pattern_surface
};
/**
diff --git a/src/cairoint.h b/src/cairoint.h
index 21c5d62..8166436 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -823,6 +823,11 @@ struct _cairo_surface_backend {
const cairo_solid_pattern_t *solid_pattern);
cairo_bool_t
+ (*can_repaint_solid_pattern_surface)
+ (void *surface,
+ const cairo_solid_pattern_t *solid_pattern);
+
+ cairo_bool_t
(*has_show_text_glyphs) (void *surface);
cairo_warn cairo_int_status_t
diff --git a/src/test-meta-surface.c b/src/test-meta-surface.c
index 42bf6b0..d5e14d7 100644
--- a/src/test-meta-surface.c
+++ b/src/test-meta-surface.c
@@ -336,6 +336,7 @@ static const cairo_surface_backend_t test_meta_surface_backend = {
NULL, /* reset */
NULL, /* fill_stroke */
NULL, /* create_solid_pattern_surface */
+ NULL, /* can_repaint_solid_pattern_surface */
_test_meta_surface_has_show_text_glyphs,
_test_meta_surface_show_text_glyphs
};
diff --git a/src/test-paginated-surface.c b/src/test-paginated-surface.c
index 4c56647..d42700c 100644
--- a/src/test-paginated-surface.c
+++ b/src/test-paginated-surface.c
@@ -326,6 +326,7 @@ static const cairo_surface_backend_t test_paginated_surface_backend = {
NULL, /* reset */
NULL, /* fill_stroke */
NULL, /* create_solid_pattern_surface */
+ NULL, /* can_repaint_solid_pattern_surface */
_test_paginated_surface_has_show_text_glyphs,
_test_paginated_surface_show_text_glyphs
commit 0df43251d4b4641d16c0a2e2c49d18dd2a9c832e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Dec 17 23:45:39 2008 +0000
[replay] Take advantage of unresolved fonts
As Behdad has changed the underlying ft-font to accept unresolved patterns,
take advantage of that to simplify the replay code.
diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c
index b97d936..28e449e 100644
--- a/util/cairo-script/cairo-script-operators.c
+++ b/util/cairo-script/cairo-script-operators.c
@@ -1628,8 +1628,7 @@ _ft_create_for_pattern (csi_t *ctx,
struct _ft_face_data *data;
csi_list_t *link;
cairo_font_face_t *font_face;
- FcPattern *pattern, *resolved;
- FcResult result;
+ FcPattern *pattern;
csi_status_t status;
_csi_blob_init (&tmpl, (uint8_t *) string->string, string->len);
@@ -1646,18 +1645,7 @@ _ft_create_for_pattern (csi_t *ctx,
if (_csi_unlikely (pattern == NULL))
return _csi_error (CSI_STATUS_NO_MEMORY);
- FcConfigSubstitute (NULL, pattern, FcMatchPattern);
- FcDefaultSubstitute (pattern);
-
- resolved = FcFontMatch (NULL, pattern, &result);
- if (_csi_unlikely (resolved == NULL)) {
- FcPatternDestroy (pattern);
- return _csi_error (CSI_STATUS_NO_MEMORY);
- }
-
- font_face = cairo_ft_font_face_create_for_pattern (resolved);
-
- FcPatternDestroy (resolved);
+ font_face = cairo_ft_font_face_create_for_pattern (pattern);
FcPatternDestroy (pattern);
data = _csi_slab_alloc (ctx, sizeof (*data));
commit 97a00bdd4eefade8d0808b5572bcdbba26c9c8f3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Dec 17 17:32:07 2008 +0000
[cairoint.h] Wrap macro in parenthesis
Ensure that the stride calculation macro is not influenced by surrounding
precedence issues by enclosing it in a pair of parenthesis.
diff --git a/src/cairoint.h b/src/cairoint.h
index 819d534..21c5d62 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2067,7 +2067,7 @@ _cairo_surface_has_device_transform (cairo_surface_t *surface);
/* pixman-required stride alignment in bytes. */
#define CAIRO_STRIDE_ALIGNMENT (sizeof (uint32_t))
#define CAIRO_STRIDE_FOR_WIDTH_BPP(w,bpp) \
- (((bpp)*(w)+7)/8 + CAIRO_STRIDE_ALIGNMENT-1) & ~(CAIRO_STRIDE_ALIGNMENT-1)
+ ((((bpp)*(w)+7)/8 + CAIRO_STRIDE_ALIGNMENT-1) & -CAIRO_STRIDE_ALIGNMENT)
#define CAIRO_CONTENT_VALID(content) ((content) && \
(((content) & ~(CAIRO_CONTENT_COLOR | \
commit aa65e756d496f4c3a8b43d2100e17dc39c2c26b7
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Dec 5 11:21:11 2008 +0000
[script] Avoid creating 0x0 windows
XCreateWindow dies if asked to create a 0x0 window, so don't and use a 1x1
pixel window for a zero-sized surface.
diff --git a/util/cairo-script/csi-replay.c b/util/cairo-script/csi-replay.c
index 0b4a6bf..ea2b0d4 100644
--- a/util/cairo-script/csi-replay.c
+++ b/util/cairo-script/csi-replay.c
@@ -56,8 +56,10 @@ _surface_create (void *closure,
attr.override_redirect = True;
w = XCreateWindow (dpy, DefaultRootWindow (dpy), 0, 0,
- width, height, 0, xrender_format->depth,
- InputOutput, visual, CWOverrideRedirect, &attr);
+ width <= 0 ? 1 : width,
+ height <= 0 ? 1 : height,
+ 0, xrender_format->depth,
+ InputOutput, visual, CWOverrideRedirect, &attr);
XMapWindow (dpy, w);
surface = cairo_xlib_surface_create_with_xrender_format (dpy, w,
commit 6458903c95c2bba3f1b9ceaaafb6979d180ab039
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Dec 17 10:07:32 2008 +0000
[image] Eliminate the short-lived context used for coercing.
When coercing from one image format to another we performed a paint
operation using a temporary context - this is overkill as we can just call
_cairo_surface_paint() directly.
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 9b997a9..e9e544d 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -1524,35 +1524,41 @@ const cairo_surface_backend_t _cairo_image_surface_backend = {
/* A convenience function for when one needs to coerce an image
* surface to an alternate format. */
cairo_image_surface_t *
-_cairo_image_surface_clone (cairo_image_surface_t *surface,
- cairo_format_t format)
+_cairo_image_surface_coerce (cairo_image_surface_t *surface,
+ cairo_format_t format)
{
cairo_image_surface_t *clone;
+ cairo_surface_pattern_t pattern;
cairo_status_t status;
- cairo_t *cr;
- double x, y;
- clone = (cairo_image_surface_t *)
- cairo_image_surface_create (format,
- surface->width, surface->height);
+ status = surface->base.status;
+ if (unlikely (status))
+ return (cairo_image_surface_t *)_cairo_surface_create_in_error (status);
- cairo_surface_get_device_offset (&surface->base, &x, &y);
- cairo_surface_set_device_offset (&clone->base, x, y);
- clone->transparency = CAIRO_IMAGE_UNKNOWN;
+ if (surface->format == format)
+ return (cairo_image_surface_t *)cairo_surface_reference(&surface->base);
- /* XXX Use _cairo_surface_composite directly */
- cr = cairo_create (&clone->base);
- cairo_set_source_surface (cr, &surface->base, 0, 0);
- cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
- cairo_paint (cr);
- status = cairo_status (cr);
- cairo_destroy (cr);
+ clone = (cairo_image_surface_t *)
+ cairo_image_surface_create (format, surface->width, surface->height);
+ if (unlikely (clone->base.status))
+ return clone;
+
+ _cairo_pattern_init_for_surface (&pattern, &surface->base);
+ status = _cairo_surface_paint (&clone->base,
+ CAIRO_OPERATOR_SOURCE,
+ &pattern.base, NULL);
+ _cairo_pattern_fini (&pattern.base);
if (unlikely (status)) {
cairo_surface_destroy (&clone->base);
- return (cairo_image_surface_t *) _cairo_surface_create_in_error (status);
+ return (cairo_image_surface_t *)_cairo_surface_create_in_error (status);
}
+ clone->base.device_transform =
+ surface->base.device_transform;
+ clone->base.device_transform_inverse =
+ surface->base.device_transform_inverse;
+
return clone;
}
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index ffae4d6..52b6fa5 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -2077,32 +2077,34 @@ static cairo_status_t
_trace_mask_to_path (cairo_image_surface_t *mask,
cairo_path_fixed_t *path)
{
- cairo_status_t status;
- cairo_image_surface_t *a1_mask;
- uint8_t *row, *byte_ptr, byte;
+ const uint8_t *row;
int rows, cols, bytes_per_row;
int x, y, bit;
double xoff, yoff;
+ cairo_status_t status;
- if (mask->format == CAIRO_FORMAT_A1)
- a1_mask = (cairo_image_surface_t *) cairo_surface_reference (&mask->base);
- else
- a1_mask = _cairo_image_surface_clone (mask, CAIRO_FORMAT_A1);
-
- status = cairo_surface_status (&a1_mask->base);
- if (unlikely (status)) {
- cairo_surface_destroy (&a1_mask->base);
+ mask = _cairo_image_surface_coerce (mask, CAIRO_FORMAT_A1);
+ status = mask->base.status;
+ if (unlikely (status))
return status;
- }
cairo_surface_get_device_offset (&mask->base, &xoff, &yoff);
- bytes_per_row = (a1_mask->width + 7) / 8;
- for (y = 0, row = a1_mask->data, rows = a1_mask->height; rows; row += a1_mask->stride, rows--, y++) {
- for (x = 0, byte_ptr = row, cols = bytes_per_row; cols; byte_ptr++, cols--) {
- byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte_ptr);
- for (bit = 7; bit >= 0 && x < a1_mask->width; bit--, x++) {
- if (byte & (1 << bit)) {
+ bytes_per_row = (mask->width + 7) / 8;
+ row = mask->data;
+ for (y = 0, rows = mask->height; rows--; row += mask->stride, y++) {
+ const uint8_t *byte_ptr = row;
+ x = 0;
+ for (cols = bytes_per_row; cols--; ) {
+ uint8_t byte = *byte_ptr++;
+ if (byte == 0) {
+ x += 8;
+ continue;
+ }
+
+ byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (byte);
+ for (bit = 1 << 7; bit && x < mask->width; bit >>= 1, x++) {
+ if (byte & bit) {
status = _add_unit_rectangle_to_path (path,
x - xoff, y - yoff);
if (unlikely (status))
@@ -2113,7 +2115,7 @@ _trace_mask_to_path (cairo_image_surface_t *mask,
}
BAIL:
- cairo_surface_destroy (&a1_mask->base);
+ cairo_surface_destroy (&mask->base);
return status;
}
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index e81ccd8..db554a1 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -657,8 +657,8 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
cairo_scaled_font_t *scaled_font,
unsigned long glyph_index)
{
- cairo_image_surface_t *image;
cairo_scaled_glyph_t *scaled_glyph;
+ cairo_image_surface_t *image;
cairo_status_t status;
uint8_t *row, *byte;
int rows, cols;
@@ -666,18 +666,17 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
status = _cairo_scaled_glyph_lookup (scaled_font,
glyph_index,
- CAIRO_SCALED_GLYPH_INFO_METRICS|
+ CAIRO_SCALED_GLYPH_INFO_METRICS |
CAIRO_SCALED_GLYPH_INFO_SURFACE,
&scaled_glyph);
if (unlikely (status))
return status;
- image = scaled_glyph->surface;
- if (image->format != CAIRO_FORMAT_A1) {
- image = _cairo_image_surface_clone (image, CAIRO_FORMAT_A1);
- if (cairo_surface_status (&image->base))
- return cairo_surface_status (&image->base);
- }
+ image = _cairo_image_surface_coerce (scaled_glyph->surface,
+ CAIRO_FORMAT_A1);
+ status = image->base.status;
+ if (unlikely (status))
+ return status;
_cairo_output_stream_printf (document->xml_node_glyphs, "<g");
_cairo_svg_surface_emit_transform (document->xml_node_glyphs, " transform",
@@ -698,8 +697,7 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
}
_cairo_output_stream_printf (document->xml_node_glyphs, "</g>\n");
- if (image != scaled_glyph->surface)
- cairo_surface_destroy (&image->base);
+ cairo_surface_destroy (&image->base);
return CAIRO_STATUS_SUCCESS;
}
diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c
index b3a4831..3ff5003 100644
--- a/src/cairo-type3-glyph-surface.c
+++ b/src/cairo-type3-glyph-surface.c
@@ -87,18 +87,6 @@ _cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface,
cairo_matrix_t *image_matrix)
{
cairo_status_t status;
- cairo_image_surface_t *image_mask;
-
- /* The only image type supported by Type 3 fonts are 1-bit image
- * masks */
- if (image->format == CAIRO_FORMAT_A1) {
- image_mask = image;
- } else {
- image_mask = _cairo_image_surface_clone (image, CAIRO_FORMAT_A1);
- status = cairo_surface_status (&image->base);
- if (unlikely (status))
- return status;
- }
_cairo_output_stream_printf (surface->stream,
"q %f %f %f %f %f %f cm\n",
@@ -109,14 +97,14 @@ _cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface,
image_matrix->x0,
image_matrix->y0);
- status = surface->emit_image (image_mask, surface->stream);
+ /* The only image type supported by Type 3 fonts are 1-bit masks */
+ image = _cairo_image_surface_coerce (image, CAIRO_FORMAT_A1);
+ status = surface->emit_image (image, surface->stream);
+ cairo_surface_destroy (&image->base);
_cairo_output_stream_printf (surface->stream,
"Q\n");
- if (image_mask != image)
- cairo_surface_destroy (&image_mask->base);
-
return status;
}
diff --git a/src/cairoint.h b/src/cairoint.h
index 55752f5..819d534 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2139,8 +2139,8 @@ _cairo_image_surface_set_clip_region (void *abstract_surface,
cairo_region_t *region);
cairo_private cairo_image_surface_t *
-_cairo_image_surface_clone (cairo_image_surface_t *surface,
- cairo_format_t format);
+_cairo_image_surface_coerce (cairo_image_surface_t *surface,
+ cairo_format_t format);
cairo_private cairo_image_transparency_t
_cairo_image_analyze_transparency (cairo_image_surface_t *image);
commit 9b46d13b6cd58c711010df89a41b216c5cc8c881
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Dec 17 23:52:32 2008 +0000
[trace] Runtime version check.
Check that the application is using cairo >= 1.9 before attempting to
query the mime-data.
diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c
index 1b27fe4..30656a1 100644
--- a/util/cairo-trace/trace.c
+++ b/util/cairo-trace/trace.c
@@ -1137,11 +1137,6 @@ _emit_image (cairo_surface_t *image,
uint8_t *rowdata;
uint8_t *data;
struct _data_stream stream;
- const char *mime_types[] = {
- CAIRO_MIME_TYPE_JPEG,
- CAIRO_MIME_TYPE_PNG,
- NULL
- }, **mime_type;
if (cairo_surface_status (image)) {
fprintf (logfile,
@@ -1173,24 +1168,32 @@ _emit_image (cairo_surface_t *image,
va_end (ap);
}
- for (mime_type = mime_types; *mime_type; mime_type++) {
- const unsigned char *mime_data;
- unsigned int mime_length;
+ if (cairo_version () >= CAIRO_VERSION_ENCODE (1, 9, 0)) {
+ const char *mime_types[] = {
+ CAIRO_MIME_TYPE_JPEG,
+ CAIRO_MIME_TYPE_PNG,
+ NULL
+ }, **mime_type;
- cairo_surface_get_mime_data (image, *mime_type,
- &mime_data, &mime_length);
- if (mime_data != NULL) {
- fprintf (logfile,
- " /mime-type (%s) set\n"
- " /source <~",
- *mime_type);
- _write_base85_data_start (&stream);
- _write_base85_data (&stream, mime_data, mime_length);
- _write_base85_data_end (&stream);
- fprintf (logfile,
- "~> set\n"
- " image");
- return;
+ for (mime_type = mime_types; *mime_type; mime_type++) {
+ const unsigned char *mime_data;
+ unsigned int mime_length;
+
+ cairo_surface_get_mime_data (image, *mime_type,
+ &mime_data, &mime_length);
+ if (mime_data != NULL) {
+ fprintf (logfile,
+ " /mime-type (%s) set\n"
+ " /source <~",
+ *mime_type);
+ _write_base85_data_start (&stream);
+ _write_base85_data (&stream, mime_data, mime_length);
+ _write_base85_data_end (&stream);
+ fprintf (logfile,
+ "~> set\n"
+ " image");
+ return;
+ }
}
}
commit 2d790daa957471670f4ae0d3b22da89e4ee7111f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 18 00:47:08 2008 +0000
[pattern] Use a solid pattern for a uniform gradient.
If each color stop in a gradient is identical, replace the gradient
surface with a simple solid surface. As seen in the wild.
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 9477f87..3a4a9c8 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -2073,19 +2073,15 @@ _cairo_pattern_acquire_surface (const cairo_pattern_t *pattern,
if (src->n_stops)
{
- cairo_color_t color;
-
- _cairo_color_init_rgba (&color,
- src->stops->color.red,
- src->stops->color.green,
- src->stops->color.blue,
- src->stops->color.alpha);
-
- _cairo_pattern_init_solid (&solid, &color, CAIRO_CONTENT_COLOR_ALPHA);
+ _cairo_pattern_init_solid (&solid,
+ &src->stops->color,
+ CAIRO_CONTENT_COLOR_ALPHA);
}
else
{
- _cairo_pattern_init_solid (&solid, CAIRO_COLOR_TRANSPARENT, CAIRO_CONTENT_ALPHA);
+ _cairo_pattern_init_solid (&solid,
+ CAIRO_COLOR_TRANSPARENT,
+ CAIRO_CONTENT_ALPHA);
}
status = _cairo_pattern_acquire_surface_for_solid (&solid, dst,
@@ -2096,11 +2092,39 @@ _cairo_pattern_acquire_surface (const cairo_pattern_t *pattern,
}
else
{
- status = _cairo_pattern_acquire_surface_for_gradient (src, dst,
- x, y,
- width, height,
- surface_out,
- attributes);
+ unsigned int i;
+
+ /* Is the gradient a uniform colour?
+ * Happens more often than you would believe.
+ */
+ for (i = 1; i < src->n_stops; i++) {
+ if (! _cairo_color_equal (&src->stops[0].color,
+ &src->stops[i].color))
+ {
+ break;
+ }
+ }
+ if (i == src->n_stops) {
+ cairo_solid_pattern_t solid;
+
+ _cairo_pattern_init_solid (&solid,
+ &src->stops->color,
+ CAIRO_CONTENT_COLOR_ALPHA);
+
+ status =
+ _cairo_pattern_acquire_surface_for_solid (&solid, dst,
+ x, y,
+ width, height,
+ surface_out,
+ attributes);
+ } else {
+ status =
+ _cairo_pattern_acquire_surface_for_gradient (src, dst,
+ x, y,
+ width, height,
+ surface_out,
+ attributes);
+ }
}
} break;
case CAIRO_PATTERN_TYPE_SURFACE: {
commit 25a4677200ea6689be0dca9d533842dc7da54837
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Dec 17 09:29:35 2008 +0000
[analysis] Use approximate extents.
Use the approximate path based extents to avoid tessellation.
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index 50005c2..0529a74 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -446,7 +446,6 @@ _cairo_analysis_surface_stroke (void *abstract_surface,
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t status, backend_status;
- cairo_traps_t traps;
cairo_rectangle_int_t extents;
cairo_bool_t is_empty;
@@ -478,26 +477,22 @@ _cairo_analysis_surface_stroke (void *abstract_surface,
is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
if (_cairo_operator_bounded_by_mask (op)) {
- cairo_box_t box;
-
- _cairo_box_from_rectangle (&box, &extents);
-
- _cairo_traps_init (&traps);
- _cairo_traps_limit (&traps, &box);
- status = _cairo_path_fixed_stroke_to_traps (path,
- style,
- ctm, ctm_inverse,
- tolerance,
- &traps);
- if (unlikely (status)) {
- _cairo_traps_fini (&traps);
- return status;
- }
+ cairo_rectangle_int_t mask_extents;
+ double dx, dy;
+
+ _cairo_path_fixed_approximate_extents (path, &mask_extents);
+
+ _cairo_stroke_style_max_distance_from_path (style, ctm, &dx, &dy);
+
+ mask_extents.width += mask_extents.x + ceil (dx);
+ mask_extents.x -= ceil (dx);
+ mask_extents.width -= mask_extents.x;
- _cairo_traps_extents (&traps, &box);
- _cairo_traps_fini (&traps);
+ mask_extents.height += mask_extents.y + ceil (dy);
+ mask_extents.y -= ceil (dy);
+ mask_extents.height -= mask_extents.y;
- _cairo_box_round_to_rectangle (&box, &extents);
+ is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
}
if (stroke_extents)
*stroke_extents = extents;
@@ -519,7 +514,6 @@ _cairo_analysis_surface_fill (void *abstract_surface,
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t status, backend_status;
- cairo_traps_t traps;
cairo_rectangle_int_t extents;
cairo_bool_t is_empty;
@@ -550,25 +544,11 @@ _cairo_analysis_surface_fill (void *abstract_surface,
is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
if (_cairo_operator_bounded_by_mask (op)) {
- cairo_box_t box;
-
- _cairo_box_from_rectangle (&box, &extents);
-
- _cairo_traps_init (&traps);
- _cairo_traps_limit (&traps, &box);
- status = _cairo_path_fixed_fill_to_traps (path,
- fill_rule,
- tolerance,
- &traps);
- if (unlikely (status)) {
- _cairo_traps_fini (&traps);
- return status;
- }
+ cairo_rectangle_int_t mask_extents;
- _cairo_traps_extents (&traps, &box);
- _cairo_traps_fini (&traps);
+ _cairo_path_fixed_approximate_extents (path, &mask_extents);
- _cairo_box_round_to_rectangle (&box, &extents);
+ is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
}
if (fill_extents)
*fill_extents = extents;
More information about the cairo-commit
mailing list