summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cairo-analysis-surface.c6
-rw-r--r--src/cairo-gl-glyphs.c35
-rw-r--r--src/cairo-gl-private.h13
-rw-r--r--src/cairo-scaled-font.c23
-rw-r--r--src/cairo-surface-fallback.c3
-rw-r--r--src/cairo-xcb-surface.c3
-rw-r--r--src/cairo-xlib-surface.c3
-rw-r--r--src/cairoint.h3
8 files changed, 66 insertions, 23 deletions
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index eb1e87d4..5faa1b96 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -568,7 +568,8 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface,
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
glyphs,
num_glyphs,
- &glyph_extents);
+ &glyph_extents,
+ NULL);
if (unlikely (status))
return status;
@@ -651,7 +652,8 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
glyphs,
num_glyphs,
- &glyph_extents);
+ &glyph_extents,
+ NULL);
if (unlikely (status))
return status;
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index 2e8cf777..5be984f9 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -344,18 +344,19 @@ _cairo_gl_surface_show_glyphs (void *abstract_dst,
cairo_solid_pattern_t solid_pattern;
cairo_gl_glyphs_setup_t setup;
cairo_gl_composite_setup_t composite_setup;
+ cairo_bool_t overlap;
GLuint vbo = 0;
if (! GLEW_ARB_vertex_buffer_object)
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ return UNSUPPORTED ("requires ARB_vertex_buffer_object");
if (! _cairo_gl_operator_is_supported (op))
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ return UNSUPPORTED ("unsupported operator");
/* Just let unbounded operators go through the fallback code
* instead of trying to do the fixups here */
if (! _cairo_operator_bounded_by_mask (op))
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ return UNSUPPORTED ("unhandled unbound operator");
/* For CLEAR, cairo's rendering equation (quoting Owen's description in:
* http://lists.cairographics.org/archives/cairo/2005-August/004992.html)
@@ -404,34 +405,38 @@ _cairo_gl_surface_show_glyphs (void *abstract_dst,
* But for now, fall back :)
*/
if (op == CAIRO_OPERATOR_SOURCE)
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ return UNSUPPORTED ("not handling SOURCE operator");
/* XXX we don't need ownership of the font as we use a global
* glyph cache -- but we do need scaled_glyph eviction notification. :-(
*/
if (! _cairo_gl_surface_owns_font (dst, scaled_font))
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ return UNSUPPORTED ("do not control font");
if (clip != NULL) {
status = _cairo_clip_get_region (clip, &clip_region);
- if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
- return CAIRO_STATUS_SUCCESS;
- else if (status != CAIRO_STATUS_SUCCESS)
+ /* the empty clip should never be propagated this far */
+ assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO);
+ if (unlikely (_cairo_status_is_error (status)))
return status;
+ if (status == CAIRO_INT_STATUS_UNSUPPORTED)
+ return UNSUPPORTED ("unhandled clipmask");
}
- /* XXX If glyphs overlap, build tmp mask and composite.
- * Could we use the stencil instead but only write if alpha !=0 ?
- * TEXKILL? PIXELKILL?
- * Antialiasing issues - but using glyph images cause their own anyway.
- */
-
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
glyphs, num_glyphs,
- &extents);
+ &extents,
+ &overlap);
if (unlikely (status))
return status;
+ /* If the glyphs overlap, we need to build an intermediate mask rather
+ * then compositing directly.
+ * For the time being, just fallback.
+ */
+ if (overlap)
+ return UNSUPPORTED ("overlapping glyphs");
+
status = _cairo_gl_operand_init (&composite_setup.src, source, dst,
extents.x, extents.y,
extents.x, extents.y,
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index e8988eb3..378272bc 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -50,6 +50,19 @@
#define GL_GLEXT_PROTOTYPES
#include <GL/glext.h>
+#define DEBUG_GL 0
+
+#if DEBUG_GL && __GNUC__
+#define UNSUPPORTED(reason) ({ \
+ fprintf (stderr, \
+ "cairo-gl: hit unsupported operation in %s(), line %d: %s\n", \
+ __FUNCTION__, __LINE__, reason); \
+ CAIRO_INT_STATUS_UNSUPPORTED; \
+})
+#else
+#define UNSUPPORTED(reason) CAIRO_INT_STATUS_UNSUPPORTED
+#endif
+
typedef struct _cairo_gl_surface {
cairo_surface_t base;
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 2b5b26dd..3238c848 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -1902,6 +1902,15 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
}
slim_hidden_def (cairo_scaled_font_text_to_glyphs);
+static inline cairo_bool_t
+_range_contains_glyph (const cairo_point_int_t *min,
+ const cairo_point_int_t *max,
+ int left, int top,
+ int right, int bottom)
+{
+ return right > min->x && left < max->x && bottom > min->y && top < max->y;
+}
+
/*
* Compute a device-space bounding box for the glyphs.
*/
@@ -1909,13 +1918,15 @@ cairo_status_t
_cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
const cairo_glyph_t *glyphs,
int num_glyphs,
- cairo_rectangle_int_t *extents)
+ cairo_rectangle_int_t *extents,
+ cairo_bool_t *overlap_out)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
- int i;
cairo_point_int_t min = { CAIRO_RECT_INT_MAX, CAIRO_RECT_INT_MAX };
cairo_point_int_t max = { CAIRO_RECT_INT_MIN, CAIRO_RECT_INT_MIN };
cairo_scaled_glyph_t *glyph_cache[64];
+ cairo_bool_t overlap = overlap_out ? FALSE : TRUE;
+ int i;
if (unlikely (scaled_font->status))
return scaled_font->status;
@@ -1954,6 +1965,11 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
right = x + _cairo_fixed_integer_ceil (scaled_glyph->bbox.p2.x);
bottom = y + _cairo_fixed_integer_ceil (scaled_glyph->bbox.p2.y);
+ if (overlap == FALSE) {
+ overlap = _range_contains_glyph (&min, &max,
+ left, top, right, bottom);
+ }
+
if (left < min.x) min.x = left;
if (right > max.x) max.x = right;
if (top < min.y) min.y = top;
@@ -1974,6 +1990,9 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
extents->width = extents->height = 0;
}
+ if (overlap_out != NULL)
+ *overlap_out = overlap;
+
return CAIRO_STATUS_SUCCESS;
}
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 9867eea8..3bfb17de 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -1151,7 +1151,8 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
glyphs,
num_glyphs,
- &glyph_extents);
+ &glyph_extents,
+ NULL);
if (unlikely (status))
return status;
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 0650f8f6..7c5731f4 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -2558,7 +2558,8 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst,
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
glyphs,
num_glyphs,
- &glyph_extents);
+ &glyph_extents,
+ NULL);
if (status)
goto BAIL;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 4bc244a5..edcb5e63 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -4196,7 +4196,8 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
glyphs,
num_glyphs,
- &glyph_extents);
+ &glyph_extents,
+ NULL);
if (unlikely (status))
goto BAIL0;
diff --git a/src/cairoint.h b/src/cairoint.h
index 6010e20f..4f839777 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1673,7 +1673,8 @@ cairo_private cairo_status_t
_cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
const cairo_glyph_t *glyphs,
int num_glyphs,
- cairo_rectangle_int_t *extents);
+ cairo_rectangle_int_t *extents,
+ cairo_bool_t *overlap);
cairo_private cairo_status_t
_cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,