michael@0: diff --git a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c michael@0: --- a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c michael@0: +++ b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c michael@0: @@ -1426,16 +1426,104 @@ _cairo_win32_printing_surface_fill (void michael@0: } michael@0: michael@0: fflush(stderr); michael@0: michael@0: return status; michael@0: } michael@0: michael@0: static cairo_int_status_t michael@0: +_cairo_win32_printing_surface_emit_win32_glyphs (cairo_win32_surface_t *surface, michael@0: + cairo_operator_t op, michael@0: + const cairo_pattern_t *source, michael@0: + cairo_glyph_t *glyphs, michael@0: + int num_glyphs, michael@0: + cairo_scaled_font_t *scaled_font, michael@0: + cairo_clip_t *clip, michael@0: + int *remaining_glyphs) michael@0: +{ michael@0: + cairo_matrix_t ctm; michael@0: + cairo_glyph_t *unicode_glyphs; michael@0: + cairo_scaled_font_subsets_glyph_t subset_glyph; michael@0: + int i, first; michael@0: + cairo_bool_t sequence_is_unicode; michael@0: + cairo_status_t status = CAIRO_STATUS_SUCCESS; michael@0: + michael@0: + /* Where possible reverse the glyph indices back to unicode michael@0: + * characters. Strings of glyphs that could not be reversed to michael@0: + * unicode will be printed with ETO_GLYPH_INDEX. michael@0: + * michael@0: + * As _cairo_win32_scaled_font_index_to_ucs4() is a slow michael@0: + * operation, the font subsetting function michael@0: + * _cairo_scaled_font_subsets_map_glyph() is used to obtain michael@0: + * the unicode value because it caches the reverse mapping in michael@0: + * the subsets. michael@0: + */ michael@0: + michael@0: + if (surface->has_ctm) { michael@0: + for (i = 0; i < num_glyphs; i++) michael@0: + cairo_matrix_transform_point (&surface->ctm, &glyphs[i].x, &glyphs[i].y); michael@0: + cairo_matrix_multiply (&ctm, &scaled_font->ctm, &surface->ctm); michael@0: + scaled_font = cairo_scaled_font_create (scaled_font->font_face, michael@0: + &scaled_font->font_matrix, michael@0: + &ctm, michael@0: + &scaled_font->options); michael@0: + } michael@0: + michael@0: + unicode_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); michael@0: + if (unicode_glyphs == NULL) michael@0: + return _cairo_error (CAIRO_STATUS_NO_MEMORY); michael@0: + michael@0: + memcpy (unicode_glyphs, glyphs, num_glyphs * sizeof (cairo_glyph_t)); michael@0: + for (i = 0; i < num_glyphs; i++) { michael@0: + status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets, michael@0: + scaled_font, michael@0: + glyphs[i].index, michael@0: + NULL, 0, michael@0: + &subset_glyph); michael@0: + if (status) michael@0: + goto fail; michael@0: + michael@0: + unicode_glyphs[i].index = subset_glyph.unicode; michael@0: + } michael@0: + michael@0: + i = 0; michael@0: + first = 0; michael@0: + sequence_is_unicode = unicode_glyphs[0].index <= 0xffff; michael@0: + while (i < num_glyphs) { michael@0: + if (i == num_glyphs - 1 || michael@0: + ((unicode_glyphs[i + 1].index < 0xffff) != sequence_is_unicode)) michael@0: + { michael@0: + status = _cairo_win32_surface_show_glyphs_internal ( michael@0: + surface, michael@0: + op, michael@0: + source, michael@0: + sequence_is_unicode ? &unicode_glyphs[first] : &glyphs[first], michael@0: + i - first + 1, michael@0: + scaled_font, michael@0: + clip, michael@0: + remaining_glyphs, michael@0: + ! sequence_is_unicode); michael@0: + first = i + 1; michael@0: + if (i < num_glyphs - 1) michael@0: + sequence_is_unicode = unicode_glyphs[i + 1].index <= 0xffff; michael@0: + } michael@0: + i++; michael@0: + } michael@0: + michael@0: +fail: michael@0: + if (surface->has_ctm) michael@0: + cairo_scaled_font_destroy (scaled_font); michael@0: + michael@0: + free (unicode_glyphs); michael@0: + michael@0: + return status; michael@0: +} michael@0: + michael@0: +static cairo_int_status_t michael@0: _cairo_win32_printing_surface_show_glyphs (void *abstract_surface, michael@0: cairo_operator_t op, michael@0: const cairo_pattern_t *source, michael@0: cairo_glyph_t *glyphs, michael@0: int num_glyphs, michael@0: cairo_scaled_font_t *scaled_font, michael@0: cairo_clip_t *clip, michael@0: int *remaining_glyphs) michael@0: @@ -1533,77 +1621,24 @@ _cairo_win32_printing_surface_show_glyph michael@0: } michael@0: } michael@0: #endif michael@0: michael@0: #if CAIRO_HAS_WIN32_FONT michael@0: if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_WIN32 && michael@0: source->type == CAIRO_PATTERN_TYPE_SOLID) michael@0: { michael@0: - cairo_matrix_t ctm; michael@0: - cairo_glyph_t *type1_glyphs = NULL; michael@0: - cairo_scaled_font_subsets_glyph_t subset_glyph; michael@0: - michael@0: - /* Calling ExtTextOutW() with ETO_GLYPH_INDEX and a Type 1 michael@0: - * font on a printer DC prints garbled text. The text displays michael@0: - * correctly on a display DC. When using a printer michael@0: - * DC, ExtTextOutW() only works with characters and not glyph michael@0: - * indices. michael@0: - * michael@0: - * For Type 1 fonts the glyph indices are converted back to michael@0: - * unicode characters before calling _cairo_win32_surface_show_glyphs(). michael@0: - * michael@0: - * As _cairo_win32_scaled_font_index_to_ucs4() is a slow michael@0: - * operation, the font subsetting function michael@0: - * _cairo_scaled_font_subsets_map_glyph() is used to obtain michael@0: - * the unicode value because it caches the reverse mapping in michael@0: - * the subsets. michael@0: - */ michael@0: - if (_cairo_win32_scaled_font_is_type1 (scaled_font)) { michael@0: - type1_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); michael@0: - if (type1_glyphs == NULL) { michael@0: - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); michael@0: - goto FINISH; michael@0: - } michael@0: - memcpy (type1_glyphs, glyphs, num_glyphs * sizeof (cairo_glyph_t)); michael@0: - for (i = 0; i < num_glyphs; i++) { michael@0: - status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets, michael@0: - scaled_font, michael@0: - type1_glyphs[i].index, michael@0: - NULL, 0, michael@0: - &subset_glyph); michael@0: - if (status) michael@0: - goto FINISH; michael@0: - michael@0: - type1_glyphs[i].index = subset_glyph.unicode; michael@0: - } michael@0: - glyphs = type1_glyphs; michael@0: - } michael@0: - michael@0: - if (surface->has_ctm || surface->has_gdi_ctm) { michael@0: - cairo_matrix_multiply (&ctm, &surface->ctm, &surface->gdi_ctm); michael@0: - for (i = 0; i < num_glyphs; i++) michael@0: - cairo_matrix_transform_point (&ctm, &glyphs[i].x, &glyphs[i].y); michael@0: - cairo_matrix_multiply (&ctm, &scaled_font->ctm, &ctm); michael@0: - scaled_font = cairo_scaled_font_create (scaled_font->font_face, michael@0: - &scaled_font->font_matrix, michael@0: - &ctm, michael@0: - &scaled_font->options); michael@0: - } michael@0: - status = _cairo_win32_surface_show_glyphs (surface, op, michael@0: - source, glyphs, michael@0: - num_glyphs, scaled_font, michael@0: - clip, michael@0: - remaining_glyphs); michael@0: - if (surface->has_ctm || surface->has_gdi_ctm) michael@0: - cairo_scaled_font_destroy (scaled_font); michael@0: - michael@0: - if (type1_glyphs != NULL) michael@0: - free (type1_glyphs); michael@0: - michael@0: + status = _cairo_win32_printing_surface_emit_win32_glyphs (surface, michael@0: + op, michael@0: + source, michael@0: + glyphs, michael@0: + num_glyphs, michael@0: + scaled_font, michael@0: + clip, michael@0: + remaining_glyphs); michael@0: goto FINISH; michael@0: } michael@0: #endif michael@0: michael@0: SaveDC (surface->dc); michael@0: old_ctm = surface->ctm; michael@0: old_has_ctm = surface->has_ctm; michael@0: surface->has_ctm = TRUE; michael@0: diff --git a/gfx/cairo/cairo/src/cairo-win32-private.h b/gfx/cairo/cairo/src/cairo-win32-private.h michael@0: --- a/gfx/cairo/cairo/src/cairo-win32-private.h michael@0: +++ b/gfx/cairo/cairo/src/cairo-win32-private.h michael@0: @@ -157,16 +157,27 @@ _cairo_win32_surface_get_extents (void michael@0: uint32_t michael@0: _cairo_win32_flags_for_dc (HDC dc); michael@0: michael@0: cairo_status_t michael@0: _cairo_win32_surface_set_clip_region (void *abstract_surface, michael@0: cairo_region_t *region); michael@0: michael@0: cairo_int_status_t michael@0: +_cairo_win32_surface_show_glyphs_internal (void *surface, michael@0: + cairo_operator_t op, michael@0: + const cairo_pattern_t *source, michael@0: + cairo_glyph_t *glyphs, michael@0: + int num_glyphs, michael@0: + cairo_scaled_font_t *scaled_font, michael@0: + cairo_clip_t *clip, michael@0: + int *remaining_glyphs, michael@0: + cairo_bool_t glyph_indices); michael@0: + michael@0: +cairo_int_status_t michael@0: _cairo_win32_surface_show_glyphs (void *surface, michael@0: cairo_operator_t op, michael@0: const cairo_pattern_t *source, michael@0: cairo_glyph_t *glyphs, michael@0: int num_glyphs, michael@0: cairo_scaled_font_t *scaled_font, michael@0: cairo_clip_t *clip, michael@0: int *remaining_glyphs); michael@0: diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c michael@0: --- a/gfx/cairo/cairo/src/cairo-win32-surface.c michael@0: +++ b/gfx/cairo/cairo/src/cairo-win32-surface.c michael@0: @@ -1607,24 +1607,25 @@ static cairo_status_t michael@0: _cairo_win32_surface_flush (void *abstract_surface) michael@0: { michael@0: return _cairo_win32_surface_set_clip_region (abstract_surface, NULL); michael@0: } michael@0: michael@0: #define STACK_GLYPH_SIZE 256 michael@0: michael@0: cairo_int_status_t michael@0: -_cairo_win32_surface_show_glyphs (void *surface, michael@0: - cairo_operator_t op, michael@0: - const cairo_pattern_t *source, michael@0: - cairo_glyph_t *glyphs, michael@0: - int num_glyphs, michael@0: - cairo_scaled_font_t *scaled_font, michael@0: - cairo_clip_t *clip, michael@0: - int *remaining_glyphs) michael@0: +_cairo_win32_surface_show_glyphs_internal (void *surface, michael@0: + cairo_operator_t op, michael@0: + const cairo_pattern_t *source, michael@0: + cairo_glyph_t *glyphs, michael@0: + int num_glyphs, michael@0: + cairo_scaled_font_t *scaled_font, michael@0: + cairo_clip_t *clip, michael@0: + int *remaining_glyphs, michael@0: + cairo_bool_t glyph_indexing) michael@0: { michael@0: #ifdef CAIRO_HAS_WIN32_FONT michael@0: if (scaled_font->backend->type == CAIRO_FONT_TYPE_DWRITE) { michael@0: #ifdef CAIRO_HAS_DWRITE_FONT michael@0: return _cairo_dwrite_show_glyphs_on_surface(surface, op, source, glyphs, num_glyphs, scaled_font, clip); michael@0: #endif michael@0: } else { michael@0: cairo_win32_surface_t *dst = surface; michael@0: @@ -1737,29 +1738,20 @@ _cairo_win32_surface_show_glyphs (void michael@0: dxy_buf[j+1] = _cairo_lround (logical_y - next_logical_y); michael@0: /* note that GDI coordinate system is inverted */ michael@0: michael@0: logical_x = next_logical_x; michael@0: logical_y = next_logical_y; michael@0: } michael@0: } michael@0: michael@0: - /* Using glyph indices for a Type 1 font does not work on a michael@0: - * printer DC. The win32 printing surface will convert the the michael@0: - * glyph indices of Type 1 fonts to the unicode values. michael@0: - */ michael@0: - if ((dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) && michael@0: - _cairo_win32_scaled_font_is_type1 (scaled_font)) michael@0: - { michael@0: + if (glyph_indexing) michael@0: + glyph_index_option = ETO_GLYPH_INDEX; michael@0: + else michael@0: glyph_index_option = 0; michael@0: - } michael@0: - else michael@0: - { michael@0: - glyph_index_option = ETO_GLYPH_INDEX; michael@0: - } michael@0: michael@0: win_result = ExtTextOutW(dst->dc, michael@0: start_x, michael@0: start_y, michael@0: glyph_index_option | ETO_PDY, michael@0: NULL, michael@0: glyph_buf, michael@0: num_glyphs, michael@0: @@ -1778,16 +1770,37 @@ _cairo_win32_surface_show_glyphs (void michael@0: } michael@0: #else michael@0: return CAIRO_INT_STATUS_UNSUPPORTED; michael@0: #endif michael@0: } michael@0: michael@0: #undef STACK_GLYPH_SIZE michael@0: michael@0: +cairo_int_status_t michael@0: +_cairo_win32_surface_show_glyphs (void *surface, michael@0: + cairo_operator_t op, michael@0: + const cairo_pattern_t *source, michael@0: + cairo_glyph_t *glyphs, michael@0: + int num_glyphs, michael@0: + cairo_scaled_font_t *scaled_font, michael@0: + cairo_clip_t *clip, michael@0: + int *remaining_glyphs) michael@0: +{ michael@0: + return _cairo_win32_surface_show_glyphs_internal (surface, michael@0: + op, michael@0: + source, michael@0: + glyphs, michael@0: + num_glyphs, michael@0: + scaled_font, michael@0: + clip, michael@0: + remaining_glyphs, michael@0: + TRUE); michael@0: +} michael@0: + michael@0: static cairo_surface_t * michael@0: cairo_win32_surface_create_internal (HDC hdc, cairo_format_t format) michael@0: { michael@0: cairo_win32_surface_t *surface; michael@0: michael@0: RECT rect; michael@0: michael@0: surface = malloc (sizeof (cairo_win32_surface_t));