From 95771d62c57c081fe350e0d33326aaa6a27139da Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Sun, 29 Jun 2008 19:31:23 +0930 Subject: [PATCH] Implement win32 index_to_ucs4 font backend function --- src/cairo-win32-font.c | 93 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c index 140093b22..7b8433486 100644 --- a/src/cairo-win32-font.c +++ b/src/cairo-win32-font.c @@ -1552,6 +1552,98 @@ fail1: return status; } +static cairo_status_t +_cairo_win32_scaled_font_index_to_ucs4 (void *abstract_font, + unsigned long index, + uint32_t *ucs4) +{ + cairo_win32_scaled_font_t *scaled_font = abstract_font; + GLYPHSET *glyph_set; + uint16_t *utf16 = NULL; + WORD *glyph_indices = NULL; + HDC hdc = NULL; + int res; + unsigned int i, j, num_glyphs; + cairo_status_t status = CAIRO_STATUS_SUCCESS; + + hdc = _get_global_font_dc (); + if (!hdc) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc); + if (status) + return status; + + res = GetFontUnicodeRanges(hdc, NULL); + if (res == 0) { + status = _cairo_win32_print_gdi_error ( + "_cairo_win32_scaled_font_index_to_ucs4:GetFontUnicodeRanges"); + goto exit1; + } + + glyph_set = malloc (res); + if (glyph_set == NULL) { + status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + goto exit1; + } + + res = GetFontUnicodeRanges(hdc, glyph_set); + if (res == 0) { + status = _cairo_win32_print_gdi_error ( + "_cairo_win32_scaled_font_index_to_ucs4:GetFontUnicodeRanges"); + goto exit1; + } + + for (i = 0; i < glyph_set->cRanges; i++) { + num_glyphs = glyph_set->ranges[i].cGlyphs; + + utf16 = _cairo_malloc_ab (num_glyphs + 1, sizeof (uint16_t)); + if (utf16 == NULL) { + status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + goto exit1; + } + + glyph_indices = _cairo_malloc_ab (num_glyphs + 1, sizeof (WORD)); + if (glyph_indices == NULL) { + status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + goto exit2; + } + + for (j = 0; j < num_glyphs; j++) + utf16[j] = glyph_set->ranges[i].wcLow + j; + utf16[j] = 0; + + if (GetGlyphIndicesW (hdc, utf16, num_glyphs, glyph_indices, 0) == GDI_ERROR) { + status = _cairo_win32_print_gdi_error ( + "_cairo_win32_scaled_font_index_to_ucs4:GetGlyphIndicesW"); + goto exit2; + } + + for (j = 0; j < num_glyphs; j++) { + if (glyph_indices[j] == index) { + *ucs4 = utf16[j]; + goto exit2; + } + } + + free (glyph_indices); + glyph_indices = NULL; + free (utf16); + utf16 = NULL; + } + +exit2: + if (glyph_indices) + free (glyph_indices); + if (utf16) + free (utf16); + free (glyph_set); +exit1: + cairo_win32_scaled_font_done_font (&scaled_font->base); + + return status; +} + static cairo_status_t _cairo_win32_scaled_font_init_glyph_surface (cairo_win32_scaled_font_t *scaled_font, cairo_scaled_glyph_t *scaled_glyph) @@ -1788,6 +1880,7 @@ const cairo_scaled_font_backend_t _cairo_win32_scaled_font_backend = { _cairo_win32_scaled_font_show_glyphs, _cairo_win32_scaled_font_load_truetype_table, _cairo_win32_scaled_font_map_glyphs_to_unicode, + _cairo_win32_scaled_font_index_to_ucs4, }; /* #cairo_win32_font_face_t */