gfx/cairo/unicode-printing.patch

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 diff --git a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
michael@0 2 --- a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
michael@0 3 +++ b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
michael@0 4 @@ -1426,16 +1426,104 @@ _cairo_win32_printing_surface_fill (void
michael@0 5 }
michael@0 6
michael@0 7 fflush(stderr);
michael@0 8
michael@0 9 return status;
michael@0 10 }
michael@0 11
michael@0 12 static cairo_int_status_t
michael@0 13 +_cairo_win32_printing_surface_emit_win32_glyphs (cairo_win32_surface_t *surface,
michael@0 14 + cairo_operator_t op,
michael@0 15 + const cairo_pattern_t *source,
michael@0 16 + cairo_glyph_t *glyphs,
michael@0 17 + int num_glyphs,
michael@0 18 + cairo_scaled_font_t *scaled_font,
michael@0 19 + cairo_clip_t *clip,
michael@0 20 + int *remaining_glyphs)
michael@0 21 +{
michael@0 22 + cairo_matrix_t ctm;
michael@0 23 + cairo_glyph_t *unicode_glyphs;
michael@0 24 + cairo_scaled_font_subsets_glyph_t subset_glyph;
michael@0 25 + int i, first;
michael@0 26 + cairo_bool_t sequence_is_unicode;
michael@0 27 + cairo_status_t status = CAIRO_STATUS_SUCCESS;
michael@0 28 +
michael@0 29 + /* Where possible reverse the glyph indices back to unicode
michael@0 30 + * characters. Strings of glyphs that could not be reversed to
michael@0 31 + * unicode will be printed with ETO_GLYPH_INDEX.
michael@0 32 + *
michael@0 33 + * As _cairo_win32_scaled_font_index_to_ucs4() is a slow
michael@0 34 + * operation, the font subsetting function
michael@0 35 + * _cairo_scaled_font_subsets_map_glyph() is used to obtain
michael@0 36 + * the unicode value because it caches the reverse mapping in
michael@0 37 + * the subsets.
michael@0 38 + */
michael@0 39 +
michael@0 40 + if (surface->has_ctm) {
michael@0 41 + for (i = 0; i < num_glyphs; i++)
michael@0 42 + cairo_matrix_transform_point (&surface->ctm, &glyphs[i].x, &glyphs[i].y);
michael@0 43 + cairo_matrix_multiply (&ctm, &scaled_font->ctm, &surface->ctm);
michael@0 44 + scaled_font = cairo_scaled_font_create (scaled_font->font_face,
michael@0 45 + &scaled_font->font_matrix,
michael@0 46 + &ctm,
michael@0 47 + &scaled_font->options);
michael@0 48 + }
michael@0 49 +
michael@0 50 + unicode_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
michael@0 51 + if (unicode_glyphs == NULL)
michael@0 52 + return _cairo_error (CAIRO_STATUS_NO_MEMORY);
michael@0 53 +
michael@0 54 + memcpy (unicode_glyphs, glyphs, num_glyphs * sizeof (cairo_glyph_t));
michael@0 55 + for (i = 0; i < num_glyphs; i++) {
michael@0 56 + status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets,
michael@0 57 + scaled_font,
michael@0 58 + glyphs[i].index,
michael@0 59 + NULL, 0,
michael@0 60 + &subset_glyph);
michael@0 61 + if (status)
michael@0 62 + goto fail;
michael@0 63 +
michael@0 64 + unicode_glyphs[i].index = subset_glyph.unicode;
michael@0 65 + }
michael@0 66 +
michael@0 67 + i = 0;
michael@0 68 + first = 0;
michael@0 69 + sequence_is_unicode = unicode_glyphs[0].index <= 0xffff;
michael@0 70 + while (i < num_glyphs) {
michael@0 71 + if (i == num_glyphs - 1 ||
michael@0 72 + ((unicode_glyphs[i + 1].index < 0xffff) != sequence_is_unicode))
michael@0 73 + {
michael@0 74 + status = _cairo_win32_surface_show_glyphs_internal (
michael@0 75 + surface,
michael@0 76 + op,
michael@0 77 + source,
michael@0 78 + sequence_is_unicode ? &unicode_glyphs[first] : &glyphs[first],
michael@0 79 + i - first + 1,
michael@0 80 + scaled_font,
michael@0 81 + clip,
michael@0 82 + remaining_glyphs,
michael@0 83 + ! sequence_is_unicode);
michael@0 84 + first = i + 1;
michael@0 85 + if (i < num_glyphs - 1)
michael@0 86 + sequence_is_unicode = unicode_glyphs[i + 1].index <= 0xffff;
michael@0 87 + }
michael@0 88 + i++;
michael@0 89 + }
michael@0 90 +
michael@0 91 +fail:
michael@0 92 + if (surface->has_ctm)
michael@0 93 + cairo_scaled_font_destroy (scaled_font);
michael@0 94 +
michael@0 95 + free (unicode_glyphs);
michael@0 96 +
michael@0 97 + return status;
michael@0 98 +}
michael@0 99 +
michael@0 100 +static cairo_int_status_t
michael@0 101 _cairo_win32_printing_surface_show_glyphs (void *abstract_surface,
michael@0 102 cairo_operator_t op,
michael@0 103 const cairo_pattern_t *source,
michael@0 104 cairo_glyph_t *glyphs,
michael@0 105 int num_glyphs,
michael@0 106 cairo_scaled_font_t *scaled_font,
michael@0 107 cairo_clip_t *clip,
michael@0 108 int *remaining_glyphs)
michael@0 109 @@ -1533,77 +1621,24 @@ _cairo_win32_printing_surface_show_glyph
michael@0 110 }
michael@0 111 }
michael@0 112 #endif
michael@0 113
michael@0 114 #if CAIRO_HAS_WIN32_FONT
michael@0 115 if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_WIN32 &&
michael@0 116 source->type == CAIRO_PATTERN_TYPE_SOLID)
michael@0 117 {
michael@0 118 - cairo_matrix_t ctm;
michael@0 119 - cairo_glyph_t *type1_glyphs = NULL;
michael@0 120 - cairo_scaled_font_subsets_glyph_t subset_glyph;
michael@0 121 -
michael@0 122 - /* Calling ExtTextOutW() with ETO_GLYPH_INDEX and a Type 1
michael@0 123 - * font on a printer DC prints garbled text. The text displays
michael@0 124 - * correctly on a display DC. When using a printer
michael@0 125 - * DC, ExtTextOutW() only works with characters and not glyph
michael@0 126 - * indices.
michael@0 127 - *
michael@0 128 - * For Type 1 fonts the glyph indices are converted back to
michael@0 129 - * unicode characters before calling _cairo_win32_surface_show_glyphs().
michael@0 130 - *
michael@0 131 - * As _cairo_win32_scaled_font_index_to_ucs4() is a slow
michael@0 132 - * operation, the font subsetting function
michael@0 133 - * _cairo_scaled_font_subsets_map_glyph() is used to obtain
michael@0 134 - * the unicode value because it caches the reverse mapping in
michael@0 135 - * the subsets.
michael@0 136 - */
michael@0 137 - if (_cairo_win32_scaled_font_is_type1 (scaled_font)) {
michael@0 138 - type1_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
michael@0 139 - if (type1_glyphs == NULL) {
michael@0 140 - status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
michael@0 141 - goto FINISH;
michael@0 142 - }
michael@0 143 - memcpy (type1_glyphs, glyphs, num_glyphs * sizeof (cairo_glyph_t));
michael@0 144 - for (i = 0; i < num_glyphs; i++) {
michael@0 145 - status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets,
michael@0 146 - scaled_font,
michael@0 147 - type1_glyphs[i].index,
michael@0 148 - NULL, 0,
michael@0 149 - &subset_glyph);
michael@0 150 - if (status)
michael@0 151 - goto FINISH;
michael@0 152 -
michael@0 153 - type1_glyphs[i].index = subset_glyph.unicode;
michael@0 154 - }
michael@0 155 - glyphs = type1_glyphs;
michael@0 156 - }
michael@0 157 -
michael@0 158 - if (surface->has_ctm || surface->has_gdi_ctm) {
michael@0 159 - cairo_matrix_multiply (&ctm, &surface->ctm, &surface->gdi_ctm);
michael@0 160 - for (i = 0; i < num_glyphs; i++)
michael@0 161 - cairo_matrix_transform_point (&ctm, &glyphs[i].x, &glyphs[i].y);
michael@0 162 - cairo_matrix_multiply (&ctm, &scaled_font->ctm, &ctm);
michael@0 163 - scaled_font = cairo_scaled_font_create (scaled_font->font_face,
michael@0 164 - &scaled_font->font_matrix,
michael@0 165 - &ctm,
michael@0 166 - &scaled_font->options);
michael@0 167 - }
michael@0 168 - status = _cairo_win32_surface_show_glyphs (surface, op,
michael@0 169 - source, glyphs,
michael@0 170 - num_glyphs, scaled_font,
michael@0 171 - clip,
michael@0 172 - remaining_glyphs);
michael@0 173 - if (surface->has_ctm || surface->has_gdi_ctm)
michael@0 174 - cairo_scaled_font_destroy (scaled_font);
michael@0 175 -
michael@0 176 - if (type1_glyphs != NULL)
michael@0 177 - free (type1_glyphs);
michael@0 178 -
michael@0 179 + status = _cairo_win32_printing_surface_emit_win32_glyphs (surface,
michael@0 180 + op,
michael@0 181 + source,
michael@0 182 + glyphs,
michael@0 183 + num_glyphs,
michael@0 184 + scaled_font,
michael@0 185 + clip,
michael@0 186 + remaining_glyphs);
michael@0 187 goto FINISH;
michael@0 188 }
michael@0 189 #endif
michael@0 190
michael@0 191 SaveDC (surface->dc);
michael@0 192 old_ctm = surface->ctm;
michael@0 193 old_has_ctm = surface->has_ctm;
michael@0 194 surface->has_ctm = TRUE;
michael@0 195 diff --git a/gfx/cairo/cairo/src/cairo-win32-private.h b/gfx/cairo/cairo/src/cairo-win32-private.h
michael@0 196 --- a/gfx/cairo/cairo/src/cairo-win32-private.h
michael@0 197 +++ b/gfx/cairo/cairo/src/cairo-win32-private.h
michael@0 198 @@ -157,16 +157,27 @@ _cairo_win32_surface_get_extents (void
michael@0 199 uint32_t
michael@0 200 _cairo_win32_flags_for_dc (HDC dc);
michael@0 201
michael@0 202 cairo_status_t
michael@0 203 _cairo_win32_surface_set_clip_region (void *abstract_surface,
michael@0 204 cairo_region_t *region);
michael@0 205
michael@0 206 cairo_int_status_t
michael@0 207 +_cairo_win32_surface_show_glyphs_internal (void *surface,
michael@0 208 + cairo_operator_t op,
michael@0 209 + const cairo_pattern_t *source,
michael@0 210 + cairo_glyph_t *glyphs,
michael@0 211 + int num_glyphs,
michael@0 212 + cairo_scaled_font_t *scaled_font,
michael@0 213 + cairo_clip_t *clip,
michael@0 214 + int *remaining_glyphs,
michael@0 215 + cairo_bool_t glyph_indices);
michael@0 216 +
michael@0 217 +cairo_int_status_t
michael@0 218 _cairo_win32_surface_show_glyphs (void *surface,
michael@0 219 cairo_operator_t op,
michael@0 220 const cairo_pattern_t *source,
michael@0 221 cairo_glyph_t *glyphs,
michael@0 222 int num_glyphs,
michael@0 223 cairo_scaled_font_t *scaled_font,
michael@0 224 cairo_clip_t *clip,
michael@0 225 int *remaining_glyphs);
michael@0 226 diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c
michael@0 227 --- a/gfx/cairo/cairo/src/cairo-win32-surface.c
michael@0 228 +++ b/gfx/cairo/cairo/src/cairo-win32-surface.c
michael@0 229 @@ -1607,24 +1607,25 @@ static cairo_status_t
michael@0 230 _cairo_win32_surface_flush (void *abstract_surface)
michael@0 231 {
michael@0 232 return _cairo_win32_surface_set_clip_region (abstract_surface, NULL);
michael@0 233 }
michael@0 234
michael@0 235 #define STACK_GLYPH_SIZE 256
michael@0 236
michael@0 237 cairo_int_status_t
michael@0 238 -_cairo_win32_surface_show_glyphs (void *surface,
michael@0 239 - cairo_operator_t op,
michael@0 240 - const cairo_pattern_t *source,
michael@0 241 - cairo_glyph_t *glyphs,
michael@0 242 - int num_glyphs,
michael@0 243 - cairo_scaled_font_t *scaled_font,
michael@0 244 - cairo_clip_t *clip,
michael@0 245 - int *remaining_glyphs)
michael@0 246 +_cairo_win32_surface_show_glyphs_internal (void *surface,
michael@0 247 + cairo_operator_t op,
michael@0 248 + const cairo_pattern_t *source,
michael@0 249 + cairo_glyph_t *glyphs,
michael@0 250 + int num_glyphs,
michael@0 251 + cairo_scaled_font_t *scaled_font,
michael@0 252 + cairo_clip_t *clip,
michael@0 253 + int *remaining_glyphs,
michael@0 254 + cairo_bool_t glyph_indexing)
michael@0 255 {
michael@0 256 #ifdef CAIRO_HAS_WIN32_FONT
michael@0 257 if (scaled_font->backend->type == CAIRO_FONT_TYPE_DWRITE) {
michael@0 258 #ifdef CAIRO_HAS_DWRITE_FONT
michael@0 259 return _cairo_dwrite_show_glyphs_on_surface(surface, op, source, glyphs, num_glyphs, scaled_font, clip);
michael@0 260 #endif
michael@0 261 } else {
michael@0 262 cairo_win32_surface_t *dst = surface;
michael@0 263 @@ -1737,29 +1738,20 @@ _cairo_win32_surface_show_glyphs (void
michael@0 264 dxy_buf[j+1] = _cairo_lround (logical_y - next_logical_y);
michael@0 265 /* note that GDI coordinate system is inverted */
michael@0 266
michael@0 267 logical_x = next_logical_x;
michael@0 268 logical_y = next_logical_y;
michael@0 269 }
michael@0 270 }
michael@0 271
michael@0 272 - /* Using glyph indices for a Type 1 font does not work on a
michael@0 273 - * printer DC. The win32 printing surface will convert the the
michael@0 274 - * glyph indices of Type 1 fonts to the unicode values.
michael@0 275 - */
michael@0 276 - if ((dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) &&
michael@0 277 - _cairo_win32_scaled_font_is_type1 (scaled_font))
michael@0 278 - {
michael@0 279 + if (glyph_indexing)
michael@0 280 + glyph_index_option = ETO_GLYPH_INDEX;
michael@0 281 + else
michael@0 282 glyph_index_option = 0;
michael@0 283 - }
michael@0 284 - else
michael@0 285 - {
michael@0 286 - glyph_index_option = ETO_GLYPH_INDEX;
michael@0 287 - }
michael@0 288
michael@0 289 win_result = ExtTextOutW(dst->dc,
michael@0 290 start_x,
michael@0 291 start_y,
michael@0 292 glyph_index_option | ETO_PDY,
michael@0 293 NULL,
michael@0 294 glyph_buf,
michael@0 295 num_glyphs,
michael@0 296 @@ -1778,16 +1770,37 @@ _cairo_win32_surface_show_glyphs (void
michael@0 297 }
michael@0 298 #else
michael@0 299 return CAIRO_INT_STATUS_UNSUPPORTED;
michael@0 300 #endif
michael@0 301 }
michael@0 302
michael@0 303 #undef STACK_GLYPH_SIZE
michael@0 304
michael@0 305 +cairo_int_status_t
michael@0 306 +_cairo_win32_surface_show_glyphs (void *surface,
michael@0 307 + cairo_operator_t op,
michael@0 308 + const cairo_pattern_t *source,
michael@0 309 + cairo_glyph_t *glyphs,
michael@0 310 + int num_glyphs,
michael@0 311 + cairo_scaled_font_t *scaled_font,
michael@0 312 + cairo_clip_t *clip,
michael@0 313 + int *remaining_glyphs)
michael@0 314 +{
michael@0 315 + return _cairo_win32_surface_show_glyphs_internal (surface,
michael@0 316 + op,
michael@0 317 + source,
michael@0 318 + glyphs,
michael@0 319 + num_glyphs,
michael@0 320 + scaled_font,
michael@0 321 + clip,
michael@0 322 + remaining_glyphs,
michael@0 323 + TRUE);
michael@0 324 +}
michael@0 325 +
michael@0 326 static cairo_surface_t *
michael@0 327 cairo_win32_surface_create_internal (HDC hdc, cairo_format_t format)
michael@0 328 {
michael@0 329 cairo_win32_surface_t *surface;
michael@0 330
michael@0 331 RECT rect;
michael@0 332
michael@0 333 surface = malloc (sizeof (cairo_win32_surface_t));

mercurial