summaryrefslogtreecommitdiffstats
path: root/gfx/cairo/unicode-printing.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/cairo/unicode-printing.patch')
-rw-r--r--gfx/cairo/unicode-printing.patch333
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 000000000..09b3991ea
--- /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));