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.

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

mercurial