Implement win32 index_to_ucs4 font backend function

This commit is contained in:
Adrian Johnson 2008-06-29 19:31:23 +09:30
parent 4619b0b309
commit 95771d62c5

View file

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