diff options
Diffstat (limited to 'gfx/cairo/cairo/src/win32/cairo-win32-font.c')
-rw-r--r-- | gfx/cairo/cairo/src/win32/cairo-win32-font.c | 257 |
1 files changed, 19 insertions, 238 deletions
diff --git a/gfx/cairo/cairo/src/win32/cairo-win32-font.c b/gfx/cairo/cairo/src/win32/cairo-win32-font.c index 3452c6cf4e..a561e74a44 100644 --- a/gfx/cairo/cairo/src/win32/cairo-win32-font.c +++ b/gfx/cairo/cairo/src/win32/cairo-win32-font.c @@ -33,15 +33,6 @@ * Contributor(s): */ -#define WIN32_LEAN_AND_MEAN -/* We require Windows 2000 features such as GetGlyphIndices */ -#if !defined(WINVER) || (WINVER < 0x0500) -# define WINVER 0x0500 -#endif -#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) -# define _WIN32_WINNT 0x0500 -#endif - #include "cairoint.h" #include "cairo-win32-private.h" @@ -71,12 +62,15 @@ /** * SECTION:cairo-win32-fonts - * @Title: Win32 Fonts + * @Title: Win32 GDI Fonts * @Short_Description: Font support for Microsoft Windows * @See_Also: #cairo_font_face_t * * The Microsoft Windows font backend is primarily used to render text on * Microsoft Windows systems. + * + * Note: Win32 GDI fonts do not support color fonts. Use DWrite fonts + * if color font support is required. **/ /** @@ -650,226 +644,6 @@ _cairo_win32_scaled_font_fini (void *abstract_font) DeleteObject (scaled_font->unscaled_hfont); } -static cairo_int_status_t -_cairo_win32_scaled_font_type1_text_to_glyphs (cairo_win32_scaled_font_t *scaled_font, - double x, - double y, - const char *utf8, - cairo_glyph_t **glyphs, - int *num_glyphs) -{ - uint16_t *utf16; - int n16; - int i; - WORD *glyph_indices = NULL; - cairo_status_t status; - double x_pos, y_pos; - HDC hdc = NULL; - cairo_matrix_t mat; - - status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &n16); - if (status) - return status; - - glyph_indices = _cairo_malloc_ab (n16 + 1, sizeof (WORD)); - if (!glyph_indices) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL1; - } - - hdc = _get_global_font_dc (); - assert (hdc != NULL); - - status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc); - if (status) - goto FAIL2; - - if (GetGlyphIndicesW (hdc, utf16, n16, glyph_indices, 0) == GDI_ERROR) { - status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_type1_text_to_glyphs:GetGlyphIndicesW"); - goto FAIL3; - } - - *num_glyphs = n16; - *glyphs = _cairo_malloc_ab (n16, sizeof (cairo_glyph_t)); - if (!*glyphs) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL3; - } - - x_pos = x; - y_pos = y; - - mat = scaled_font->base.ctm; - status = cairo_matrix_invert (&mat); - assert (status == CAIRO_STATUS_SUCCESS); - - _cairo_scaled_font_freeze_cache (&scaled_font->base); - - for (i = 0; i < n16; i++) { - cairo_scaled_glyph_t *scaled_glyph; - - (*glyphs)[i].index = glyph_indices[i]; - (*glyphs)[i].x = x_pos; - (*glyphs)[i].y = y_pos; - - status = _cairo_scaled_glyph_lookup (&scaled_font->base, - glyph_indices[i], - CAIRO_SCALED_GLYPH_INFO_METRICS, - &scaled_glyph); - if (status) { - free (*glyphs); - *glyphs = NULL; - break; - } - - x = scaled_glyph->x_advance; - y = scaled_glyph->y_advance; - cairo_matrix_transform_distance (&mat, &x, &y); - x_pos += x; - y_pos += y; - } - - _cairo_scaled_font_thaw_cache (&scaled_font->base); - -FAIL3: - cairo_win32_scaled_font_done_font (&scaled_font->base); -FAIL2: - free (glyph_indices); -FAIL1: - free (utf16); - - return status; -} - -static cairo_int_status_t -_cairo_win32_scaled_font_text_to_glyphs (void *abstract_font, - double x, - double y, - const char *utf8, - cairo_glyph_t **glyphs, - int *num_glyphs) -{ - cairo_win32_scaled_font_t *scaled_font = abstract_font; - uint16_t *utf16; - int n16; - GCP_RESULTSW gcp_results; - unsigned int buffer_size, i; - WCHAR *glyph_indices = NULL; - int *dx = NULL; - cairo_status_t status; - double x_pos, y_pos; - double x_incr, y_incr; - HDC hdc = NULL; - - /* GetCharacterPlacement() returns utf16 instead of glyph indices - * for Type 1 fonts. Use GetGlyphIndices for Type 1 fonts. */ - if (scaled_font->is_type1) - return _cairo_win32_scaled_font_type1_text_to_glyphs (scaled_font, - x, - y, - utf8, - glyphs, - num_glyphs); - - /* Compute a vector in user space along the baseline of length one logical space unit */ - x_incr = 1; - y_incr = 0; - cairo_matrix_transform_distance (&scaled_font->base.font_matrix, &x_incr, &y_incr); - x_incr /= scaled_font->logical_scale; - y_incr /= scaled_font->logical_scale; - - status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &n16); - if (status) - return status; - - gcp_results.lStructSize = sizeof (GCP_RESULTS); - gcp_results.lpOutString = NULL; - gcp_results.lpOrder = NULL; - gcp_results.lpCaretPos = NULL; - gcp_results.lpClass = NULL; - - buffer_size = MAX (n16 * 1.2, 16); /* Initially guess number of chars plus a few */ - if (buffer_size > INT_MAX) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL1; - } - - hdc = _get_global_font_dc (); - assert (hdc != NULL); - - status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc); - if (status) - goto FAIL1; - - while (TRUE) { - free (glyph_indices); - glyph_indices = NULL; - - free (dx); - dx = NULL; - - glyph_indices = _cairo_malloc_ab (buffer_size, sizeof (WCHAR)); - dx = _cairo_malloc_ab (buffer_size, sizeof (int)); - if (!glyph_indices || !dx) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL2; - } - - gcp_results.nGlyphs = buffer_size; - gcp_results.lpDx = dx; - gcp_results.lpGlyphs = glyph_indices; - - if (!GetCharacterPlacementW (hdc, utf16, n16, - 0, - &gcp_results, - GCP_DIACRITIC | GCP_LIGATE | GCP_GLYPHSHAPE | GCP_REORDER)) { - status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_text_to_glyphs"); - goto FAIL2; - } - - if (gcp_results.lpDx && gcp_results.lpGlyphs) - break; - - /* Too small a buffer, try again */ - - buffer_size += buffer_size / 2; - if (buffer_size > INT_MAX) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL2; - } - } - - *num_glyphs = gcp_results.nGlyphs; - *glyphs = _cairo_malloc_ab (gcp_results.nGlyphs, sizeof (cairo_glyph_t)); - if (!*glyphs) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL2; - } - - x_pos = x; - y_pos = y; - - for (i = 0; i < gcp_results.nGlyphs; i++) { - (*glyphs)[i].index = glyph_indices[i]; - (*glyphs)[i].x = x_pos ; - (*glyphs)[i].y = y_pos; - - x_pos += x_incr * dx[i]; - y_pos += y_incr * dx[i]; - } - - FAIL2: - free (glyph_indices); - free (dx); - - cairo_win32_scaled_font_done_font (&scaled_font->base); - - FAIL1: - free (utf16); - - return status; -} - static unsigned long _cairo_win32_scaled_font_ucs4_to_index (void *abstract_font, uint32_t ucs4) @@ -1319,7 +1093,8 @@ _draw_glyphs_on_surface (cairo_win32_surface_t *surface, static cairo_int_status_t _cairo_win32_scaled_font_glyph_init (void *abstract_font, cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_glyph_info_t info) + cairo_scaled_glyph_info_t info, + const cairo_color_t *foreground_color) { cairo_win32_scaled_font_t *scaled_font = abstract_font; cairo_status_t status; @@ -1330,6 +1105,12 @@ _cairo_win32_scaled_font_glyph_init (void *abstract_font, return status; } + if (info & CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE) { + scaled_glyph->color_glyph = FALSE; + scaled_glyph->color_glyph_set = TRUE; + return CAIRO_INT_STATUS_UNSUPPORTED; + } + if (info & CAIRO_SCALED_GLYPH_INFO_SURFACE) { status = _cairo_win32_scaled_font_init_glyph_surface (scaled_font, scaled_glyph); if (status) @@ -1554,9 +1335,9 @@ _cairo_win32_scaled_font_load_type1_data (void *abstract_font, length); } -static cairo_surface_t * -_compute_mask (cairo_surface_t *surface, - int quality) +cairo_surface_t * +_cairo_compute_glyph_mask (cairo_surface_t *surface, + int quality) { cairo_image_surface_t *glyph; cairo_image_surface_t *mask; @@ -1640,7 +1421,7 @@ _cairo_win32_scaled_font_init_glyph_surface (cairo_win32_scaled_font_t *scaled_f if (status) goto FAIL; - image = _compute_mask (surface, scaled_font->quality); + image = _cairo_compute_glyph_mask (surface, scaled_font->quality); status = image->status; if (status) goto FAIL; @@ -1843,7 +1624,7 @@ const cairo_scaled_font_backend_t _cairo_win32_scaled_font_backend = { CAIRO_FONT_TYPE_WIN32, _cairo_win32_scaled_font_fini, _cairo_win32_scaled_font_glyph_init, - NULL, /* _cairo_win32_scaled_font_text_to_glyphs, FIXME */ + NULL, /* _cairo_win32_scaled_font_text_to_glyphs */ _cairo_win32_scaled_font_ucs4_to_index, _cairo_win32_scaled_font_load_truetype_table, _cairo_win32_scaled_font_index_to_ucs4, @@ -1960,7 +1741,7 @@ _cairo_win32_font_face_init_key (cairo_win32_font_face_t *key, LOGFONTW *logfont, HFONT font) { - unsigned long hash = _CAIRO_HASH_INIT_VALUE; + uintptr_t hash = _CAIRO_HASH_INIT_VALUE; key->logfont = *logfont; key->hfont = font; @@ -2017,7 +1798,7 @@ _cairo_win32_font_face_scaled_font_create (void *abstract_face, 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)) { + _is_scale (font_matrix, -font_face->logfont.lfHeight * WIN32_FONT_LOGICAL_SCALE)) { hfont = font_face->hfont; } } |