Index: gfx/cairo/cairo/src/cairo-win32-font.c =================================================================== RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo-win32-font.c,v retrieving revision 1.21 diff -u -p -1 -2 -r1.21 cairo-win32-font.c --- gfx/cairo/cairo/src/cairo-win32-font.c 4 Apr 2007 01:09:15 -0000 1.21 +++ gfx/cairo/cairo/src/cairo-win32-font.c 14 Apr 2007 09:05:25 -0000 @@ -218,27 +218,33 @@ _get_system_quality (void) } if (smoothing_type == FE_FONTSMOOTHINGCLEARTYPE) return CLEARTYPE_QUALITY; } return ANTIALIASED_QUALITY; } else { return DEFAULT_QUALITY; } } +/* If face_hfont is non-NULL then font_matrix must be a simple scale by some + * factor S, ctm must be the identity, logfont->lfHeight must be -S, + * logfont->lfWidth, logfont->lfEscapement, logfont->lfOrientation must + * all be 0, and face_hfont is the result of calling CreateFontIndirectW on + * logfont. + */ static cairo_scaled_font_t * _win32_scaled_font_create (LOGFONTW *logfont, - HFONT hfont, + HFONT face_hfont, cairo_font_face_t *font_face, const cairo_matrix_t *font_matrix, const cairo_matrix_t *ctm, const cairo_font_options_t *options) { cairo_win32_scaled_font_t *f; cairo_matrix_t scale; cairo_status_t status; _cairo_win32_initialize (); f = malloc (sizeof(cairo_win32_scaled_font_t)); @@ -268,29 +274,38 @@ _win32_scaled_font_create (LOGFONTW case CAIRO_ANTIALIAS_SUBPIXEL: if (_have_cleartype_quality ()) f->quality = CLEARTYPE_QUALITY; else f->quality = ANTIALIASED_QUALITY; break; case CAIRO_ANTIALIAS_DEFAULT: ASSERT_NOT_REACHED; } } f->em_square = 0; - f->scaled_hfont = hfont; + f->scaled_hfont = NULL; f->unscaled_hfont = NULL; - - /* don't delete the hfont if it was passed in to us */ - f->delete_scaled_hfont = !hfont; + if (f->quality == logfont->lfQuality || + (logfont->lfQuality == DEFAULT_QUALITY && + options->antialias == CAIRO_ANTIALIAS_DEFAULT)) { + /* If face_hfont is non-NULL, then we can use it to avoid creating our + * own --- because the constraints on face_hfont mentioned above + * guarantee it was created in exactly the same way that + * _win32_scaled_font_get_scaled_hfont would create it. + */ + f->scaled_hfont = face_hfont; + } + /* don't delete the hfont if we're using the one passed in to us */ + f->delete_scaled_hfont = !f->scaled_hfont; cairo_matrix_multiply (&scale, font_matrix, ctm); _compute_transform (f, &scale); _cairo_scaled_font_init (&f->base, font_face, font_matrix, ctm, options, &cairo_win32_scaled_font_backend); status = _cairo_win32_scaled_font_set_metrics (f); if (status) { cairo_scaled_font_destroy (&f->base); return NULL; @@ -1479,133 +1494,177 @@ const cairo_scaled_font_backend_t cairo_ _cairo_win32_scaled_font_glyph_init, _cairo_win32_scaled_font_text_to_glyphs, NULL, /* ucs4_to_index */ _cairo_win32_scaled_font_show_glyphs, _cairo_win32_scaled_font_load_truetype_table, _cairo_win32_scaled_font_map_glyphs_to_unicode, }; /* cairo_win32_font_face_t */ typedef struct _cairo_win32_font_face cairo_win32_font_face_t; +/* If hfont is non-NULL then logfont->lfHeight must be -S for some S, + * logfont->lfWidth, logfont->lfEscapement, logfont->lfOrientation must + * all be 0, and hfont is the result of calling CreateFontIndirectW on + * logfont. + */ struct _cairo_win32_font_face { cairo_font_face_t base; LOGFONTW logfont; HFONT hfont; }; /* implement the platform-specific interface */ static void _cairo_win32_font_face_destroy (void *abstract_face) { } +static cairo_bool_t +_is_scale (const cairo_matrix_t *matrix, double scale) +{ + return matrix->xx == scale && matrix->yy == scale && + matrix->xy == 0. && matrix->yx == 0. && + matrix->x0 == 0. && matrix->y0 == 0.; +} + static cairo_status_t _cairo_win32_font_face_scaled_font_create (void *abstract_face, const cairo_matrix_t *font_matrix, const cairo_matrix_t *ctm, const cairo_font_options_t *options, cairo_scaled_font_t **font) { + HFONT hfont = NULL; + cairo_win32_font_face_t *font_face = abstract_face; _cairo_win32_initialize (); + if (font_face->hfont) { + /* Check whether it's OK to go ahead and use the font-face's HFONT. */ + if (_is_scale (ctm, 1.) && + _is_scale (font_matrix, -font_face->logfont.lfHeight)) { + hfont = font_face->hfont; + } + } + *font = _win32_scaled_font_create (&font_face->logfont, - font_face->hfont, + hfont, &font_face->base, font_matrix, ctm, options); if (*font) return CAIRO_STATUS_SUCCESS; else return CAIRO_STATUS_NO_MEMORY; } static const cairo_font_face_backend_t _cairo_win32_font_face_backend = { CAIRO_FONT_TYPE_WIN32, _cairo_win32_font_face_destroy, _cairo_win32_font_face_scaled_font_create }; /** - * cairo_win32_font_face_create_for_logfontw: + * cairo_win32_font_face_create_for_logfontw_hfont: * @logfont: A #LOGFONTW structure specifying the font to use. - * The lfHeight, lfWidth, lfOrientation and lfEscapement - * fields of this structure are ignored. + * If hfont is null then the lfHeight, lfWidth, lfOrientation and lfEscapement + * fields of this structure are ignored. Otherwise lfWidth, lfOrientation and + * lfEscapement must be zero. + * @font: An #HFONT that can be used when the font matrix is a scale by + * -lfHeight and the CTM is identity. * * Creates a new font for the Win32 font backend based on a * #LOGFONT. This font can then be used with * cairo_set_font_face() or cairo_scaled_font_create(). * The #cairo_scaled_font_t * returned from cairo_scaled_font_create() is also for the Win32 backend * and can be used with functions such as cairo_win32_scaled_font_select_font(). * * Return value: a newly created #cairo_font_face_t. Free with * cairo_font_face_destroy() when you are done using it. **/ cairo_font_face_t * -cairo_win32_font_face_create_for_logfontw (LOGFONTW *logfont) +cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font) { cairo_win32_font_face_t *font_face; _cairo_win32_initialize (); font_face = malloc (sizeof (cairo_win32_font_face_t)); if (!font_face) { - _cairo_error (CAIRO_STATUS_NO_MEMORY); - return (cairo_font_face_t *)&_cairo_font_face_nil; + _cairo_error (CAIRO_STATUS_NO_MEMORY); + return (cairo_font_face_t *)&_cairo_font_face_nil; } font_face->logfont = *logfont; - font_face->hfont = NULL; + font_face->hfont = font; _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend); return &font_face->base; } /** + * cairo_win32_font_face_create_for_logfontw: + * @logfont: A #LOGFONTW structure specifying the font to use. + * The lfHeight, lfWidth, lfOrientation and lfEscapement + * fields of this structure are ignored. + * + * Creates a new font for the Win32 font backend based on a + * #LOGFONT. This font can then be used with + * cairo_set_font_face() or cairo_scaled_font_create(). + * The #cairo_scaled_font_t + * returned from cairo_scaled_font_create() is also for the Win32 backend + * and can be used with functions such as cairo_win32_scaled_font_select_font(). + * + * Return value: a newly created #cairo_font_face_t. Free with + * cairo_font_face_destroy() when you are done using it. + **/ +cairo_font_face_t * +cairo_win32_font_face_create_for_logfontw (LOGFONTW *logfont) +{ + return cairo_win32_font_face_create_for_logfontw_hfont (logfont, NULL); +} + +/** * cairo_win32_font_face_create_for_hfont: * @font: An #HFONT structure specifying the font to use. * * Creates a new font for the Win32 font backend based on a * #HFONT. This font can then be used with * cairo_set_font_face() or cairo_scaled_font_create(). * The #cairo_scaled_font_t * returned from cairo_scaled_font_create() is also for the Win32 backend * and can be used with functions such as cairo_win32_scaled_font_select_font(). * * Return value: a newly created #cairo_font_face_t. Free with * cairo_font_face_destroy() when you are done using it. **/ cairo_font_face_t * cairo_win32_font_face_create_for_hfont (HFONT font) { - cairo_win32_font_face_t *font_face; - - _cairo_win32_initialize (); + LOGFONTW logfont; + GetObject (font, sizeof(logfont), &logfont); - font_face = malloc (sizeof (cairo_win32_font_face_t)); - if (!font_face) { - _cairo_error (CAIRO_STATUS_NO_MEMORY); - return (cairo_font_face_t *)&_cairo_font_face_nil; + if (logfont.lfEscapement != 0 || logfont.lfOrientation != 0 || + logfont.lfWidth != 0) { + /* We can't use this font because that optimization requires that + * lfEscapement, lfOrientation and lfWidth be zero. */ + font = NULL; } - font_face->hfont = font; - - _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend); - - return &font_face->base; + return cairo_win32_font_face_create_for_logfontw_hfont (&logfont, font); } /** * cairo_win32_scaled_font_select_font: * @scaled_font: A #cairo_scaled_font_t from the Win32 font backend. Such an * object can be created with cairo_win32_scaled_font_create_for_logfontw(). * @hdc: a device context * * Selects the font into the given device context and changes the * map mode and world transformation of the device context to match * that of the font. This function is intended for use when using * layout APIs such as Uniscribe to do text layout with the Index: gfx/cairo/cairo/src/cairo-win32.h =================================================================== RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo-win32.h,v retrieving revision 1.14 diff -u -p -1 -2 -r1.14 cairo-win32.h --- gfx/cairo/cairo/src/cairo-win32.h 24 Jan 2007 23:53:03 -0000 1.14 +++ gfx/cairo/cairo/src/cairo-win32.h 14 Apr 2007 09:05:25 -0000 @@ -61,24 +61,27 @@ cairo_win32_surface_create_with_dib (cai cairo_public HDC cairo_win32_surface_get_dc (cairo_surface_t *surface); cairo_public cairo_surface_t * cairo_win32_surface_get_image (cairo_surface_t *surface); cairo_public cairo_font_face_t * cairo_win32_font_face_create_for_logfontw (LOGFONTW *logfont); cairo_public cairo_font_face_t * cairo_win32_font_face_create_for_hfont (HFONT font); +cairo_public cairo_font_face_t * +cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font); + cairo_public cairo_status_t cairo_win32_scaled_font_select_font (cairo_scaled_font_t *scaled_font, HDC hdc); cairo_public void cairo_win32_scaled_font_done_font (cairo_scaled_font_t *scaled_font); cairo_public double cairo_win32_scaled_font_get_metrics_factor (cairo_scaled_font_t *scaled_font); cairo_public void cairo_win32_scaled_font_get_logical_to_device (cairo_scaled_font_t *scaled_font,