From efd3a965244305a069ec231b7ec28cff8d6c67c8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 24 Jan 2008 23:35:06 -0500 Subject: [PATCH] [cairo-scaled-font] Don't err on font size 0, really First, seems like we were rejecting degenerate font matrix right away at the constructor. Don't do that. Next, PS/PDF were inverting the font scale matrix, assuming that it's invertible. We now keep the inverse too, so they can use it. For the case of a size 0 font, both the scale matrix and its invert are set to 0,0,0,0. That's safe, even if slightly inconsistent. --- src/cairo-pdf-surface.c | 5 +---- src/cairo-ps-surface.c | 5 +---- src/cairo-scaled-font-private.h | 1 + src/cairo-scaled-font.c | 19 ++++++++----------- 4 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index 075fb05bf..77fd95b99 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -3575,10 +3575,7 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface, } _cairo_pdf_surface_update_object (surface, subset_resource); - matrix = font_subset->scaled_font->scale; - status = cairo_matrix_invert (&matrix); - /* _cairo_scaled_font_init ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); + matrix = font_subset->scaled_font->scale_inverse; _cairo_output_stream_printf (surface->output, "%d 0 obj\r\n" "<< /Type /Font\r\n" diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 87efa4049..5d6b3e603 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -754,10 +754,7 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface, "%% _cairo_ps_surface_emit_type3_font_subset\n"); #endif - matrix = font_subset->scaled_font->scale; - status = cairo_matrix_invert (&matrix); - /* _cairo_scaled_font_init ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); + matrix = font_subset->scaled_font->scale_inverse; _cairo_output_stream_printf (surface->final_stream, "8 dict begin\n" "/FontType 3 def\n" diff --git a/src/cairo-scaled-font-private.h b/src/cairo-scaled-font-private.h index f16487c5c..87a46166c 100644 --- a/src/cairo-scaled-font-private.h +++ b/src/cairo-scaled-font-private.h @@ -91,6 +91,7 @@ struct _cairo_scaled_font { /* "live" scaled_font members */ cairo_matrix_t scale; /* font space => device space */ + cairo_matrix_t scale_inverse; /* device space => font space */ cairo_font_extents_t extents; /* user space */ /* The mutex protects modification to all subsequent fields. */ diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index 45b6e441a..eba474c55 100644 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -191,6 +191,7 @@ const cairo_scaled_font_t _cairo_scaled_font_nil = { CAIRO_HINT_STYLE_DEFAULT, CAIRO_HINT_METRICS_DEFAULT} , { 1., 0., 0., 1., 0, 0}, /* scale */ + { 1., 0., 0., 1., 0, 0}, /* scale_inverse */ { 0., 0., 0., 0., 0. }, /* extents */ CAIRO_MUTEX_NIL_INITIALIZER,/* mutex */ NULL, /* glyphs */ @@ -463,7 +464,6 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, const cairo_font_options_t *options, const cairo_scaled_font_backend_t *backend) { - cairo_matrix_t inverse; cairo_status_t status; if (options != NULL) { @@ -472,8 +472,6 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, return status; } - /* Initialize scaled_font->scale early for easier bail out on an - * invalid matrix. */ _cairo_scaled_font_init_key (scaled_font, font_face, font_matrix, ctm, options); @@ -481,20 +479,22 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, &scaled_font->font_matrix, &scaled_font->ctm); - inverse = scaled_font->scale; - status = cairo_matrix_invert (&inverse); + scaled_font->scale_inverse = scaled_font->scale; + status = cairo_matrix_invert (&scaled_font->scale_inverse); /* If the font scale matrix rank 0, just using an all-zero inverse matrix * makes everything work correctly. This make font size 0 work without * producing an error. * * FIXME: If the scale is rank 1, we still go into error mode. But then * again, that's what we doo everywhere in cairo. + * + * Also, the check for == 0. below may bee too harsh... */ if (status && scaled_font->scale.xx == 0. && scaled_font->scale.xy == 0. && scaled_font->scale.yx == 0. && scaled_font->scale.yy == 0.) { - cairo_matrix_init (&inverse, + cairo_matrix_init (&scaled_font->scale_inverse, 0, 0, 0, 0, -scaled_font->scale.x0, -scaled_font->scale.y0); @@ -629,11 +629,8 @@ cairo_scaled_font_create (cairo_font_face_t *font_face, return (cairo_scaled_font_t *)&_cairo_scaled_font_nil; } - if (! _cairo_matrix_is_invertible (font_matrix)) - return (cairo_scaled_font_t *)&_cairo_scaled_font_nil; - - if (! _cairo_matrix_is_invertible (ctm)) - return (cairo_scaled_font_t *)&_cairo_scaled_font_nil; + /* Note that degenerate ctm or font_matrix *are* allowed. + * We want to support a font size of 0. */ font_map = _cairo_scaled_font_map_lock (); if (font_map == NULL)