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));