[cairo-commit] Branch '1.4' - 2 commits - NEWS src/cairo-image-surface.c src/cairoint.h src/cairo-scaled-font.c
Carl Worth
cworth at kemper.freedesktop.org
Mon Jan 14 15:43:29 PST 2008
NEWS | 7 +++++
src/cairo-image-surface.c | 18 +++++++++++++++
src/cairo-scaled-font.c | 55 +++++++++++++++++++++++++---------------------
src/cairoint.h | 3 ++
4 files changed, 58 insertions(+), 25 deletions(-)
New commits:
commit a6635fb5f5375b0ce2d5a1287654137f25dcc1bf
Author: Carl Worth <cworth at cworth.org>
Date: Mon Jan 14 15:41:43 2008 -0800
NEWS: Mention the mixed-format-glyphs fix and update the date.
diff --git a/NEWS b/NEWS
index 25a1ca2..64475f6 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-Release 1.4.14 (2008-01-08 Carl Worth <cworth at cworth.org>)
+Release 1.4.14 (2008-01-14 Carl Worth <cworth at cworth.org>)
==========================================================
This is the seventh update in cairo's stable 1.4 series. It comes
little more than a month after the 1.4.12 release. Compared to 1.4.12,
@@ -10,6 +10,11 @@ Fix a regression (which first appeared in 1.4.12) where stroking under
a large scale would sometimes incorrectly replace a miter join with a
bevel join. (Thanks to Keith Packard.)
+Fix handling of fonts that contain a mixture of outline and bitmapped
+glyphs. There was a change in this handling in 1.4.12 that improved
+some cases and also regressed other cases. Now, all cases should be
+handled quite well.
+
Fix xlib backend to not consider recent X server release as having a
buggy repeat implementation in the Render extension. (Thanks to
Bernardo Innocenti.)
commit 549234a27f6b25cd0577874aa2d047515041fae3
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Jan 14 16:14:02 2008 -0500
[scaled-font] Upgrade glyph mask as needed in case of mixed-format glyphs
In ecb895803b9d2a3fd142f4a2c694ca08c5581f0e Carl made fallback show_glyphs
always use a A8 mask in case of mixed-format glyphs. That's suboptimal if
there are ARGB32 glyphs. Using masks smartly we can implement the desired
behavior. Done now.
Cherry picked from commit 22d7f311f7733a57ece5d91708b2b5da9b71de86
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 27287fa..12e0b75 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -572,6 +572,24 @@ _cairo_content_from_format (cairo_format_t format)
return CAIRO_CONTENT_COLOR_ALPHA;
}
+cairo_private cairo_format_t
+_cairo_format_width (cairo_format_t format)
+{
+ switch (format) {
+ case CAIRO_FORMAT_ARGB32:
+ return 32;
+ case CAIRO_FORMAT_RGB24:
+ return 24;
+ case CAIRO_FORMAT_A8:
+ return 8;
+ case CAIRO_FORMAT_A1:
+ return 1;
+ default:
+ ASSERT_NOT_REACHED;
+ return 0;
+ }
+}
+
static cairo_surface_t *
_cairo_image_surface_create_similar (void *abstract_src,
cairo_content_t content,
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 256899b..4e474ba 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -1037,8 +1037,9 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
{
cairo_status_t status;
cairo_surface_t *mask = NULL;
- cairo_format_t mask_format;
+ cairo_format_t mask_format = CAIRO_FORMAT_A1; /* shut gcc up */
cairo_surface_pattern_t mask_pattern;
+ cairo_solid_pattern_t white_pattern;
int i;
/* These operators aren't interpreted the same way by the backends;
@@ -1068,6 +1069,8 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
status = CAIRO_STATUS_SUCCESS;
+ _cairo_pattern_init_solid (&white_pattern, CAIRO_COLOR_WHITE, CAIRO_CONTENT_COLOR);
+
_cairo_cache_freeze (scaled_font->glyphs);
for (i = 0; i < num_glyphs; i++) {
@@ -1096,31 +1099,29 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
status = mask->status;
goto CLEANUP_MASK;
}
-
- status = _cairo_surface_fill_rectangle (mask,
- CAIRO_OPERATOR_CLEAR,
- CAIRO_COLOR_TRANSPARENT,
- 0, 0,
- width, height);
- if (status)
- goto CLEANUP_MASK;
- if (mask_format == CAIRO_FORMAT_ARGB32)
- pixman_image_set_component_alpha (((cairo_image_surface_t*) mask)->
- pixman_image, TRUE);
}
- /* If we have glyphs of different formats, then the only thing
- * we can easily do is to migrate to an A8 mask. This is
- * sub-optimal if there are any component-alpha ARGB32 glyphs,
- * but pixman doesn't actually give us anyoperators that will
- * correctly ADD to a component-alpha mask. So here we are. */
+ /* If we have glyphs of different formats, we "upgrade" the mask
+ * to the wider of the formats. */
if (glyph_surface->format != mask_format &&
- mask_format != CAIRO_FORMAT_A8)
+ _cairo_format_width (mask_format) < _cairo_format_width (glyph_surface->format) )
{
cairo_surface_t *new_mask;
cairo_surface_pattern_t mask_pattern;
- mask_format = CAIRO_FORMAT_A8;
+ switch (glyph_surface->format) {
+ case CAIRO_FORMAT_ARGB32:
+ case CAIRO_FORMAT_A8:
+ case CAIRO_FORMAT_A1:
+ mask_format = glyph_surface->format;
+ break;
+ case CAIRO_FORMAT_RGB24:
+ default:
+ ASSERT_NOT_REACHED;
+ mask_format = CAIRO_FORMAT_ARGB32;
+ break;
+ }
+
new_mask = cairo_image_surface_create (mask_format,
width, height);
if (new_mask->status) {
@@ -1131,9 +1132,9 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
_cairo_pattern_init_for_surface (&mask_pattern, mask);
- status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
+ status = _cairo_surface_composite (CAIRO_OPERATOR_ADD,
+ &white_pattern.base,
&mask_pattern.base,
- NULL,
new_mask,
0, 0,
0, 0,
@@ -1161,17 +1162,17 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
_cairo_pattern_init_for_surface (&glyph_pattern, &glyph_surface->base);
status = _cairo_surface_composite (CAIRO_OPERATOR_ADD,
+ &white_pattern.base,
&glyph_pattern.base,
- NULL,
mask,
0, 0,
0, 0,
- x - dest_x,
- y - dest_y,
+ x - dest_x, y - dest_y,
glyph_surface->width,
glyph_surface->height);
_cairo_pattern_fini (&glyph_pattern.base);
+
if (status)
goto CLEANUP_MASK;
}
@@ -1179,6 +1180,10 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
if (mask != NULL) {
cairo_surface_pattern_t mask_pattern;
+ if (mask_format == CAIRO_FORMAT_ARGB32)
+ pixman_image_set_component_alpha (((cairo_image_surface_t*) mask)->
+ pixman_image, TRUE);
+
_cairo_pattern_init_for_surface (&mask_pattern, mask);
status = _cairo_surface_composite (op, pattern, &mask_pattern.base,
@@ -1194,6 +1199,8 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
CLEANUP_MASK:
_cairo_cache_thaw (scaled_font->glyphs);
+ _cairo_pattern_fini (&white_pattern.base);
+
if (mask != NULL)
cairo_surface_destroy (mask);
return status;
diff --git a/src/cairoint.h b/src/cairoint.h
index 21d43d9..6efd90e 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2022,6 +2022,9 @@ _cairo_surface_has_device_transform (cairo_surface_t *surface);
== 0))
cairo_private cairo_format_t
+_cairo_format_width (cairo_format_t format);
+
+cairo_private cairo_format_t
_cairo_format_from_content (cairo_content_t content);
cairo_private cairo_content_t
More information about the cairo-commit
mailing list