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