gfx/cairo/unicode-printing.patch

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/cairo/unicode-printing.patch	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,333 @@
     1.4 +diff --git a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
     1.5 +--- a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
     1.6 ++++ b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
     1.7 +@@ -1426,16 +1426,104 @@ _cairo_win32_printing_surface_fill (void
     1.8 +     }
     1.9 + 
    1.10 +     fflush(stderr);
    1.11 + 
    1.12 +     return status;
    1.13 + }
    1.14 + 
    1.15 + static cairo_int_status_t
    1.16 ++_cairo_win32_printing_surface_emit_win32_glyphs (cairo_win32_surface_t 	*surface,
    1.17 ++						 cairo_operator_t	 op,
    1.18 ++						 const cairo_pattern_t  *source,
    1.19 ++						 cairo_glyph_t        	*glyphs,
    1.20 ++						 int			 num_glyphs,
    1.21 ++						 cairo_scaled_font_t  	*scaled_font,
    1.22 ++						 cairo_clip_t		*clip,
    1.23 ++						 int			*remaining_glyphs)
    1.24 ++{
    1.25 ++    cairo_matrix_t ctm;
    1.26 ++    cairo_glyph_t  *unicode_glyphs;
    1.27 ++    cairo_scaled_font_subsets_glyph_t subset_glyph;
    1.28 ++    int i, first;
    1.29 ++    cairo_bool_t sequence_is_unicode;
    1.30 ++    cairo_status_t status = CAIRO_STATUS_SUCCESS;
    1.31 ++
    1.32 ++    /* Where possible reverse the glyph indices back to unicode
    1.33 ++     * characters. Strings of glyphs that could not be reversed to
    1.34 ++     * unicode will be printed with ETO_GLYPH_INDEX.
    1.35 ++     *
    1.36 ++     * As _cairo_win32_scaled_font_index_to_ucs4() is a slow
    1.37 ++     * operation, the font subsetting function
    1.38 ++     * _cairo_scaled_font_subsets_map_glyph() is used to obtain
    1.39 ++     * the unicode value because it caches the reverse mapping in
    1.40 ++     * the subsets.
    1.41 ++     */
    1.42 ++
    1.43 ++    if (surface->has_ctm) {
    1.44 ++	for (i = 0; i < num_glyphs; i++)
    1.45 ++	    cairo_matrix_transform_point (&surface->ctm, &glyphs[i].x, &glyphs[i].y);
    1.46 ++	cairo_matrix_multiply (&ctm, &scaled_font->ctm, &surface->ctm);
    1.47 ++	scaled_font = cairo_scaled_font_create (scaled_font->font_face,
    1.48 ++						&scaled_font->font_matrix,
    1.49 ++						&ctm,
    1.50 ++						&scaled_font->options);
    1.51 ++    }
    1.52 ++
    1.53 ++    unicode_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
    1.54 ++    if (unicode_glyphs == NULL)
    1.55 ++	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
    1.56 ++
    1.57 ++    memcpy (unicode_glyphs, glyphs, num_glyphs * sizeof (cairo_glyph_t));
    1.58 ++    for (i = 0; i < num_glyphs; i++) {
    1.59 ++	status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets,
    1.60 ++						       scaled_font,
    1.61 ++						       glyphs[i].index,
    1.62 ++						       NULL, 0,
    1.63 ++						       &subset_glyph);
    1.64 ++	if (status)
    1.65 ++	    goto fail;
    1.66 ++
    1.67 ++	unicode_glyphs[i].index = subset_glyph.unicode;
    1.68 ++    }
    1.69 ++
    1.70 ++    i = 0;
    1.71 ++    first = 0;
    1.72 ++    sequence_is_unicode = unicode_glyphs[0].index <= 0xffff;
    1.73 ++    while (i < num_glyphs) {
    1.74 ++	if (i == num_glyphs - 1 ||
    1.75 ++	    ((unicode_glyphs[i + 1].index < 0xffff) != sequence_is_unicode))
    1.76 ++	{
    1.77 ++	    status = _cairo_win32_surface_show_glyphs_internal (
    1.78 ++		surface,
    1.79 ++		op,
    1.80 ++		source,
    1.81 ++		sequence_is_unicode ? &unicode_glyphs[first] : &glyphs[first],
    1.82 ++		i - first + 1,
    1.83 ++		scaled_font,
    1.84 ++		clip,
    1.85 ++		remaining_glyphs,
    1.86 ++		! sequence_is_unicode);
    1.87 ++	    first = i + 1;
    1.88 ++	    if (i < num_glyphs - 1)
    1.89 ++		sequence_is_unicode = unicode_glyphs[i + 1].index <= 0xffff;
    1.90 ++	}
    1.91 ++	i++;
    1.92 ++    }
    1.93 ++
    1.94 ++fail:
    1.95 ++    if (surface->has_ctm)
    1.96 ++	cairo_scaled_font_destroy (scaled_font);
    1.97 ++
    1.98 ++    free (unicode_glyphs);
    1.99 ++
   1.100 ++    return status;
   1.101 ++}
   1.102 ++
   1.103 ++static cairo_int_status_t
   1.104 + _cairo_win32_printing_surface_show_glyphs (void                 *abstract_surface,
   1.105 +                                            cairo_operator_t	 op,
   1.106 +                                            const cairo_pattern_t *source,
   1.107 +                                            cairo_glyph_t        *glyphs,
   1.108 +                                            int			 num_glyphs,
   1.109 +                                            cairo_scaled_font_t  *scaled_font,
   1.110 + 					   cairo_clip_t		*clip,
   1.111 + 					   int			*remaining_glyphs)
   1.112 +@@ -1533,77 +1621,24 @@ _cairo_win32_printing_surface_show_glyph
   1.113 +         }
   1.114 +     }
   1.115 + #endif
   1.116 + 
   1.117 + #if CAIRO_HAS_WIN32_FONT
   1.118 +     if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_WIN32 &&
   1.119 + 	source->type == CAIRO_PATTERN_TYPE_SOLID)
   1.120 +     {
   1.121 +-	cairo_matrix_t ctm;
   1.122 +-	cairo_glyph_t  *type1_glyphs = NULL;
   1.123 +-	cairo_scaled_font_subsets_glyph_t subset_glyph;
   1.124 +-
   1.125 +-	/* Calling ExtTextOutW() with ETO_GLYPH_INDEX and a Type 1
   1.126 +-	 * font on a printer DC prints garbled text. The text displays
   1.127 +-	 * correctly on a display DC. When using a printer
   1.128 +-	 * DC, ExtTextOutW() only works with characters and not glyph
   1.129 +-	 * indices.
   1.130 +-	 *
   1.131 +-	 * For Type 1 fonts the glyph indices are converted back to
   1.132 +-	 * unicode characters before calling _cairo_win32_surface_show_glyphs().
   1.133 +-	 *
   1.134 +-	 * As _cairo_win32_scaled_font_index_to_ucs4() is a slow
   1.135 +-	 * operation, the font subsetting function
   1.136 +-	 * _cairo_scaled_font_subsets_map_glyph() is used to obtain
   1.137 +-	 * the unicode value because it caches the reverse mapping in
   1.138 +-	 * the subsets.
   1.139 +-	 */
   1.140 +-	if (_cairo_win32_scaled_font_is_type1 (scaled_font)) {
   1.141 +-	    type1_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
   1.142 +-	    if (type1_glyphs == NULL) {
   1.143 +-		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
   1.144 +-		goto FINISH;
   1.145 +-	    }
   1.146 +-	    memcpy (type1_glyphs, glyphs, num_glyphs * sizeof (cairo_glyph_t));
   1.147 +-	    for (i = 0; i < num_glyphs; i++) {
   1.148 +-		status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets,
   1.149 +-							       scaled_font,
   1.150 +-							       type1_glyphs[i].index,
   1.151 +-							       NULL, 0,
   1.152 +-							       &subset_glyph);
   1.153 +-		if (status)
   1.154 +-		    goto FINISH;
   1.155 +-
   1.156 +-		type1_glyphs[i].index = subset_glyph.unicode;
   1.157 +-	    }
   1.158 +-	    glyphs = type1_glyphs;
   1.159 +-	}
   1.160 +-
   1.161 +-	if (surface->has_ctm || surface->has_gdi_ctm) {
   1.162 +-	    cairo_matrix_multiply (&ctm, &surface->ctm, &surface->gdi_ctm);
   1.163 +-	    for (i = 0; i < num_glyphs; i++)
   1.164 +-		cairo_matrix_transform_point (&ctm, &glyphs[i].x, &glyphs[i].y);
   1.165 +-	    cairo_matrix_multiply (&ctm, &scaled_font->ctm, &ctm);
   1.166 +-	    scaled_font = cairo_scaled_font_create (scaled_font->font_face,
   1.167 +-						    &scaled_font->font_matrix,
   1.168 +-						    &ctm,
   1.169 +-						    &scaled_font->options);
   1.170 +-	}
   1.171 +-	status = _cairo_win32_surface_show_glyphs (surface, op,
   1.172 +-						   source, glyphs,
   1.173 +-						   num_glyphs, scaled_font,
   1.174 +-						   clip,
   1.175 +-						   remaining_glyphs);
   1.176 +-	if (surface->has_ctm || surface->has_gdi_ctm)
   1.177 +-	    cairo_scaled_font_destroy (scaled_font);
   1.178 +-
   1.179 +-	if (type1_glyphs != NULL)
   1.180 +-	    free (type1_glyphs);
   1.181 +-
   1.182 ++	status = _cairo_win32_printing_surface_emit_win32_glyphs (surface,
   1.183 ++								  op,
   1.184 ++								  source,
   1.185 ++								  glyphs,
   1.186 ++								  num_glyphs,
   1.187 ++								  scaled_font,
   1.188 ++								  clip,
   1.189 ++								  remaining_glyphs);
   1.190 + 	goto FINISH;
   1.191 +     }
   1.192 + #endif
   1.193 + 
   1.194 +     SaveDC (surface->dc);
   1.195 +     old_ctm = surface->ctm;
   1.196 +     old_has_ctm = surface->has_ctm;
   1.197 +     surface->has_ctm = TRUE;
   1.198 +diff --git a/gfx/cairo/cairo/src/cairo-win32-private.h b/gfx/cairo/cairo/src/cairo-win32-private.h
   1.199 +--- a/gfx/cairo/cairo/src/cairo-win32-private.h
   1.200 ++++ b/gfx/cairo/cairo/src/cairo-win32-private.h
   1.201 +@@ -157,16 +157,27 @@ _cairo_win32_surface_get_extents (void		
   1.202 + uint32_t
   1.203 + _cairo_win32_flags_for_dc (HDC dc);
   1.204 + 
   1.205 + cairo_status_t
   1.206 + _cairo_win32_surface_set_clip_region (void           *abstract_surface,
   1.207 + 				      cairo_region_t *region);
   1.208 + 
   1.209 + cairo_int_status_t
   1.210 ++_cairo_win32_surface_show_glyphs_internal (void			 *surface,
   1.211 ++					   cairo_operator_t	  op,
   1.212 ++					   const cairo_pattern_t *source,
   1.213 ++					   cairo_glyph_t	 *glyphs,
   1.214 ++					   int			  num_glyphs,
   1.215 ++					   cairo_scaled_font_t	 *scaled_font,
   1.216 ++					   cairo_clip_t		 *clip,
   1.217 ++					   int			 *remaining_glyphs,
   1.218 ++					   cairo_bool_t		  glyph_indices);
   1.219 ++
   1.220 ++cairo_int_status_t
   1.221 + _cairo_win32_surface_show_glyphs (void			*surface,
   1.222 + 				  cairo_operator_t	 op,
   1.223 + 				  const cairo_pattern_t	*source,
   1.224 + 				  cairo_glyph_t		*glyphs,
   1.225 + 				  int			 num_glyphs,
   1.226 + 				  cairo_scaled_font_t	*scaled_font,
   1.227 + 				  cairo_clip_t		*clip,
   1.228 + 				  int			*remaining_glyphs);
   1.229 +diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c
   1.230 +--- a/gfx/cairo/cairo/src/cairo-win32-surface.c
   1.231 ++++ b/gfx/cairo/cairo/src/cairo-win32-surface.c
   1.232 +@@ -1607,24 +1607,25 @@ static cairo_status_t
   1.233 + _cairo_win32_surface_flush (void *abstract_surface)
   1.234 + {
   1.235 +     return _cairo_win32_surface_set_clip_region (abstract_surface, NULL);
   1.236 + }
   1.237 + 
   1.238 + #define STACK_GLYPH_SIZE 256
   1.239 + 
   1.240 + cairo_int_status_t
   1.241 +-_cairo_win32_surface_show_glyphs (void			*surface,
   1.242 +-				  cairo_operator_t	 op,
   1.243 +-				  const cairo_pattern_t	*source,
   1.244 +-				  cairo_glyph_t		*glyphs,
   1.245 +-				  int			 num_glyphs,
   1.246 +-				  cairo_scaled_font_t	*scaled_font,
   1.247 +-				  cairo_clip_t		*clip,
   1.248 +-				  int			*remaining_glyphs)
   1.249 ++_cairo_win32_surface_show_glyphs_internal (void			*surface,
   1.250 ++					   cairo_operator_t	 op,
   1.251 ++					   const cairo_pattern_t	*source,
   1.252 ++					   cairo_glyph_t		*glyphs,
   1.253 ++					   int			 num_glyphs,
   1.254 ++					   cairo_scaled_font_t	*scaled_font,
   1.255 ++					   cairo_clip_t		*clip,
   1.256 ++					   int			*remaining_glyphs,
   1.257 ++					   cairo_bool_t           glyph_indexing)
   1.258 + {
   1.259 + #ifdef CAIRO_HAS_WIN32_FONT
   1.260 +     if (scaled_font->backend->type == CAIRO_FONT_TYPE_DWRITE) {
   1.261 + #ifdef CAIRO_HAS_DWRITE_FONT
   1.262 +         return _cairo_dwrite_show_glyphs_on_surface(surface, op, source, glyphs, num_glyphs, scaled_font, clip);
   1.263 + #endif
   1.264 +     } else {
   1.265 + 	cairo_win32_surface_t *dst = surface;
   1.266 +@@ -1737,29 +1738,20 @@ _cairo_win32_surface_show_glyphs (void		
   1.267 + 		dxy_buf[j+1] = _cairo_lround (logical_y - next_logical_y);
   1.268 + 		    /* note that GDI coordinate system is inverted */
   1.269 + 
   1.270 + 		logical_x = next_logical_x;
   1.271 + 		logical_y = next_logical_y;
   1.272 + 	    }
   1.273 + 	}
   1.274 + 
   1.275 +-	/* Using glyph indices for a Type 1 font does not work on a
   1.276 +-	 * printer DC. The win32 printing surface will convert the the
   1.277 +-	 * glyph indices of Type 1 fonts to the unicode values.
   1.278 +-	 */
   1.279 +-	if ((dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) &&
   1.280 +-	    _cairo_win32_scaled_font_is_type1 (scaled_font))
   1.281 +-	{
   1.282 ++	if (glyph_indexing)
   1.283 ++	    glyph_index_option = ETO_GLYPH_INDEX;
   1.284 ++	else
   1.285 + 	    glyph_index_option = 0;
   1.286 +-	}
   1.287 +-	else
   1.288 +-	{
   1.289 +-	    glyph_index_option = ETO_GLYPH_INDEX;
   1.290 +-	}
   1.291 + 
   1.292 + 	win_result = ExtTextOutW(dst->dc,
   1.293 + 				 start_x,
   1.294 + 				 start_y,
   1.295 + 				 glyph_index_option | ETO_PDY,
   1.296 + 				 NULL,
   1.297 + 				 glyph_buf,
   1.298 + 				 num_glyphs,
   1.299 +@@ -1778,16 +1770,37 @@ _cairo_win32_surface_show_glyphs (void		
   1.300 +     }
   1.301 + #else
   1.302 +     return CAIRO_INT_STATUS_UNSUPPORTED;
   1.303 + #endif
   1.304 + }
   1.305 + 
   1.306 + #undef STACK_GLYPH_SIZE
   1.307 + 
   1.308 ++cairo_int_status_t
   1.309 ++_cairo_win32_surface_show_glyphs (void			*surface,
   1.310 ++ 				  cairo_operator_t	 op,
   1.311 ++ 				  const cairo_pattern_t *source,
   1.312 ++ 				  cairo_glyph_t	 	*glyphs,
   1.313 ++ 				  int			 num_glyphs,
   1.314 ++ 				  cairo_scaled_font_t	*scaled_font,
   1.315 ++ 				  cairo_clip_t          *clip,
   1.316 ++ 				  int		      	*remaining_glyphs)
   1.317 ++{
   1.318 ++    return _cairo_win32_surface_show_glyphs_internal (surface,
   1.319 ++ 						      op,
   1.320 ++ 						      source,
   1.321 ++ 						      glyphs,
   1.322 ++ 						      num_glyphs,
   1.323 ++ 						      scaled_font,
   1.324 ++ 						      clip,
   1.325 ++ 						      remaining_glyphs,
   1.326 ++ 						      TRUE);
   1.327 ++}
   1.328 ++
   1.329 + static cairo_surface_t *
   1.330 + cairo_win32_surface_create_internal (HDC hdc, cairo_format_t format)
   1.331 + {
   1.332 +     cairo_win32_surface_t *surface;
   1.333 + 
   1.334 +     RECT rect;
   1.335 + 
   1.336 +     surface = malloc (sizeof (cairo_win32_surface_t));

mercurial