[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.
This commit is contained in:
Behdad Esfahbod 2008-01-24 23:35:06 -05:00
parent 45f269e330
commit efd3a96524
4 changed files with 11 additions and 19 deletions

View file

@ -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"

View file

@ -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"

View file

@ -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. */

View file

@ -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)