Bug 1857841 - pt 3. Add a new page kind named "fresh" r=glandium
[gecko.git] / gfx / cairo / 08-directwrite-additions.patch
blobb6521c4aec263b35422eadf3c021ec6a8de4c31d
1 diff --git a/gfx/cairo/cairo/src/cairo-win32.h b/gfx/cairo/cairo/src/cairo-win32.h
2 --- a/gfx/cairo/cairo/src/cairo-win32.h
3 +++ b/gfx/cairo/cairo/src/cairo-win32.h
4 @@ -69,9 +69,15 @@ cairo_win32_surface_create_with_dib (cai
5 cairo_public HDC
6 cairo_win32_surface_get_dc (cairo_surface_t *surface);
8 +cairo_public HDC
9 +cairo_win32_get_dc_with_clip (cairo_t *cr);
11 cairo_public cairo_surface_t *
12 cairo_win32_surface_get_image (cairo_surface_t *surface);
14 +cairo_public cairo_status_t
15 +cairo_win32_surface_get_size (const cairo_surface_t *surface, int *width, int *height);
17 #if CAIRO_HAS_WIN32_FONT
20 @@ -105,8 +111,33 @@ cairo_public void
21 cairo_win32_scaled_font_get_device_to_logical (cairo_scaled_font_t *scaled_font,
22 cairo_matrix_t *device_to_logical);
24 +cairo_public BYTE
25 +cairo_win32_get_system_text_quality (void);
27 #endif /* CAIRO_HAS_WIN32_FONT */
29 +#if CAIRO_HAS_DWRITE_FONT
31 +/*
32 + * Win32 DirectWrite font support
33 + */
34 +cairo_public cairo_font_face_t *
35 +cairo_dwrite_font_face_create_for_dwrite_fontface (void *dwrite_font, void *dwrite_font_face);
37 +void
38 +cairo_dwrite_scaled_font_set_force_GDI_classic (cairo_scaled_font_t *dwrite_scaled_font, cairo_bool_t allowed);
40 +cairo_bool_t
41 +cairo_dwrite_scaled_font_get_force_GDI_classic (cairo_scaled_font_t *dwrite_scaled_font);
43 +void
44 +cairo_dwrite_set_cleartype_params (FLOAT gamma, FLOAT contrast, FLOAT level, int geometry, int mode);
46 +int
47 +cairo_dwrite_get_cleartype_rendering_mode ();
49 +#endif /* CAIRO_HAS_DWRITE_FONT */
51 CAIRO_END_DECLS
53 #else /* CAIRO_HAS_WIN32_SURFACE */
54 diff --git a/gfx/cairo/cairo/src/cairo.h b/gfx/cairo/cairo/src/cairo.h
55 --- a/gfx/cairo/cairo/src/cairo.h
56 +++ b/gfx/cairo/cairo/src/cairo.h
57 @@ -1609,7 +1609,8 @@ typedef enum _cairo_font_type {
58 CAIRO_FONT_TYPE_FT,
59 CAIRO_FONT_TYPE_WIN32,
60 CAIRO_FONT_TYPE_QUARTZ,
61 - CAIRO_FONT_TYPE_USER
62 + CAIRO_FONT_TYPE_USER,
63 + CAIRO_FONT_TYPE_DWRITE
64 } cairo_font_type_t;
66 cairo_public cairo_font_type_t
67 diff --git a/gfx/cairo/cairo/src/win32/cairo-dwrite-font.cpp b/gfx/cairo/cairo/src/win32/cairo-dwrite-font.cpp
68 --- a/gfx/cairo/cairo/src/win32/cairo-dwrite-font.cpp
69 +++ b/gfx/cairo/cairo/src/win32/cairo-dwrite-font.cpp
70 @@ -37,7 +37,9 @@
71 #include "cairoint.h"
73 #include "cairo-win32-private.h"
74 +#include "cairo-pattern-private.h"
75 #include "cairo-surface-private.h"
76 +#include "cairo-image-surface-private.h"
77 #include "cairo-clip-private.h"
78 #include "cairo-win32-refptr.h"
80 @@ -136,7 +138,7 @@ ID2D1DCRenderTarget *D2DFactory::mRender
81 static cairo_status_t
82 _cairo_dwrite_font_face_create_for_toy (cairo_toy_font_face_t *toy_face,
83 cairo_font_face_t **font_face);
84 -static void
85 +static cairo_bool_t
86 _cairo_dwrite_font_face_destroy (void *font_face);
88 static cairo_status_t
89 @@ -162,22 +164,6 @@ static cairo_warn cairo_int_status_t
90 cairo_scaled_glyph_t *scaled_glyph,
91 cairo_scaled_glyph_info_t info);
93 -cairo_warn cairo_int_status_t
94 -_cairo_dwrite_scaled_show_glyphs(void *scaled_font,
95 - cairo_operator_t op,
96 - const cairo_pattern_t *pattern,
97 - cairo_surface_t *surface,
98 - int source_x,
99 - int source_y,
100 - int dest_x,
101 - int dest_y,
102 - unsigned int width,
103 - unsigned int height,
104 - cairo_glyph_t *glyphs,
105 - int num_glyphs,
106 - cairo_region_t *clip_region,
107 - int *remaining_glyphs);
109 cairo_int_status_t
110 _cairo_dwrite_load_truetype_table(void *scaled_font,
111 unsigned long tag,
112 @@ -193,33 +179,18 @@ const cairo_scaled_font_backend_t _cairo
113 CAIRO_FONT_TYPE_DWRITE,
114 _cairo_dwrite_scaled_font_fini,
115 _cairo_dwrite_scaled_glyph_init,
116 - NULL,
117 + NULL, /* text_to_glyphs */
118 _cairo_dwrite_ucs4_to_index,
119 - _cairo_dwrite_scaled_show_glyphs,
120 _cairo_dwrite_load_truetype_table,
121 - NULL,
122 + NULL, /* index_to_ucs4 */
123 + NULL, /* is_synthetic */
124 + NULL, /* index_to_glyph_name */
125 + NULL, /* load_type1_data */
126 + NULL, /* has_color_glyphs */
129 /* Helper conversion functions */
131 -/**
132 - * Get a D2D matrix from a cairo matrix. Note that D2D uses row vectors where cairo
133 - * uses column vectors. Hence the transposition.
135 - * \param Cairo matrix
136 - * \return D2D matrix
137 - */
138 -static D2D1::Matrix3x2F
139 -_cairo_d2d_matrix_from_matrix(const cairo_matrix_t *matrix)
141 - return D2D1::Matrix3x2F((FLOAT)matrix->xx,
142 - (FLOAT)matrix->yx,
143 - (FLOAT)matrix->xy,
144 - (FLOAT)matrix->yy,
145 - (FLOAT)matrix->x0,
146 - (FLOAT)matrix->y0);
151 * Get a DirectWrite matrix from a cairo matrix. Note that DirectWrite uses row
152 @@ -316,7 +287,7 @@ static cairo_status_t
153 return CAIRO_STATUS_SUCCESS;
156 -static void
157 +static cairo_bool_t
158 _cairo_dwrite_font_face_destroy (void *font_face)
160 cairo_dwrite_font_face_t *dwrite_font_face = static_cast<cairo_dwrite_font_face_t*>(font_face);
161 @@ -324,6 +295,7 @@ static void
162 dwrite_font_face->dwriteface->Release();
163 if (dwrite_font_face->font)
164 dwrite_font_face->font->Release();
165 + return TRUE;
169 @@ -507,7 +479,6 @@ static cairo_status_t
170 dwriteFont->antialias_mode = options->antialias;
173 - dwriteFont->manual_show_glyphs_allowed = TRUE;
174 dwriteFont->rendering_mode =
175 default_quality == CAIRO_ANTIALIAS_SUBPIXEL ?
176 cairo_dwrite_scaled_font_t::TEXT_RENDERING_NORMAL : cairo_dwrite_scaled_font_t::TEXT_RENDERING_NO_CLEARTYPE;
177 @@ -562,162 +533,6 @@ unsigned long
178 return index;
181 -cairo_warn cairo_int_status_t
182 -_cairo_dwrite_scaled_show_glyphs(void *scaled_font,
183 - cairo_operator_t op,
184 - const cairo_pattern_t *pattern,
185 - cairo_surface_t *generic_surface,
186 - int source_x,
187 - int source_y,
188 - int dest_x,
189 - int dest_y,
190 - unsigned int width,
191 - unsigned int height,
192 - cairo_glyph_t *glyphs,
193 - int num_glyphs,
194 - cairo_region_t *clip_region,
195 - int *remaining_glyphs)
197 - cairo_win32_surface_t *surface = (cairo_win32_surface_t *)generic_surface;
198 - cairo_int_status_t status;
200 - if (width == 0 || height == 0)
201 - return (cairo_int_status_t)CAIRO_STATUS_SUCCESS;
203 - if (_cairo_surface_is_win32 (generic_surface) &&
204 - surface->format == CAIRO_FORMAT_RGB24 &&
205 - op == CAIRO_OPERATOR_OVER) {
207 - //XXX: we need to set the clip region here
209 - status = (cairo_int_status_t)_cairo_dwrite_show_glyphs_on_surface (surface, op, pattern,
210 - glyphs, num_glyphs,
211 - (cairo_scaled_font_t*)scaled_font, NULL);
213 - return status;
214 - } else {
215 - cairo_dwrite_scaled_font_t *dwritesf =
216 - static_cast<cairo_dwrite_scaled_font_t*>(scaled_font);
217 - BOOL transform = FALSE;
219 - AutoDWriteGlyphRun run;
220 - run.allocate(num_glyphs);
221 - UINT16 *indices = const_cast<UINT16*>(run.glyphIndices);
222 - FLOAT *advances = const_cast<FLOAT*>(run.glyphAdvances);
223 - DWRITE_GLYPH_OFFSET *offsets = const_cast<DWRITE_GLYPH_OFFSET*>(run.glyphOffsets);
225 - run.bidiLevel = 0;
226 - run.fontFace = ((cairo_dwrite_font_face_t*)dwritesf->base.font_face)->dwriteface;
227 - run.isSideways = FALSE;
228 - IDWriteGlyphRunAnalysis *analysis;
230 - if (dwritesf->mat.xy == 0 && dwritesf->mat.yx == 0 &&
231 - dwritesf->mat.xx == dwritesf->base.font_matrix.xx &&
232 - dwritesf->mat.yy == dwritesf->base.font_matrix.yy) {
234 - for (int i = 0; i < num_glyphs; i++) {
235 - indices[i] = (WORD) glyphs[i].index;
236 - // Since we will multiply by our ctm matrix later for rotation effects
237 - // and such, adjust positions by the inverse matrix now.
238 - offsets[i].ascenderOffset = (FLOAT)dest_y - (FLOAT)glyphs[i].y;
239 - offsets[i].advanceOffset = (FLOAT)glyphs[i].x - dest_x;
240 - advances[i] = 0.0;
242 - run.fontEmSize = (FLOAT)dwritesf->base.font_matrix.yy;
243 - } else {
244 - transform = TRUE;
246 - for (int i = 0; i < num_glyphs; i++) {
247 - indices[i] = (WORD) glyphs[i].index;
248 - double x = glyphs[i].x - dest_x;
249 - double y = glyphs[i].y - dest_y;
250 - cairo_matrix_transform_point(&dwritesf->mat_inverse, &x, &y);
251 - // Since we will multiply by our ctm matrix later for rotation effects
252 - // and such, adjust positions by the inverse matrix now.
253 - offsets[i].ascenderOffset = -(FLOAT)y;
254 - offsets[i].advanceOffset = (FLOAT)x;
255 - advances[i] = 0.0;
257 - run.fontEmSize = 1.0f;
260 - HRESULT hr;
261 - if (!transform) {
262 - hr = DWriteFactory::Instance()->CreateGlyphRunAnalysis(&run,
263 - 1.0f,
264 - NULL,
265 - DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
266 - DWRITE_MEASURING_MODE_NATURAL,
267 - 0,
268 - 0,
269 - &analysis);
270 - } else {
271 - DWRITE_MATRIX dwmatrix = _cairo_dwrite_matrix_from_matrix(&dwritesf->mat);
272 - hr = DWriteFactory::Instance()->CreateGlyphRunAnalysis(&run,
273 - 1.0f,
274 - &dwmatrix,
275 - DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
276 - DWRITE_MEASURING_MODE_NATURAL,
277 - 0,
278 - 0,
279 - &analysis);
282 - if (FAILED(hr) || !analysis) {
283 - return CAIRO_INT_STATUS_UNSUPPORTED;
286 - RECT r;
287 - r.left = 0;
288 - r.top = 0;
289 - r.right = width;
290 - r.bottom = height;
292 - BYTE *surface = new BYTE[width * height * 3];
294 - analysis->CreateAlphaTexture(DWRITE_TEXTURE_CLEARTYPE_3x1, &r, surface, width * height * 3);
296 - cairo_image_surface_t *mask_surface =
297 - (cairo_image_surface_t*)cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
299 - cairo_surface_flush(&mask_surface->base);
301 - for (unsigned int y = 0; y < height; y++) {
302 - for (unsigned int x = 0; x < width; x++) {
303 - mask_surface->data[y * mask_surface->stride + x * 4] = surface[y * width * 3 + x * 3 + 1];
304 - mask_surface->data[y * mask_surface->stride + x * 4 + 1] = surface[y * width * 3 + x * 3 + 1];
305 - mask_surface->data[y * mask_surface->stride + x * 4 + 2] = surface[y * width * 3 + x * 3 + 1];
306 - mask_surface->data[y * mask_surface->stride + x * 4 + 3] = surface[y * width * 3 + x * 3 + 1];
309 - cairo_surface_mark_dirty(&mask_surface->base);
311 - pixman_image_set_component_alpha(mask_surface->pixman_image, 1);
313 - cairo_surface_pattern_t mask;
314 - _cairo_pattern_init_for_surface (&mask, &mask_surface->base);
316 - status = (cairo_int_status_t)_cairo_surface_composite (op, pattern,
317 - &mask.base,
318 - generic_surface,
319 - source_x, source_y,
320 - 0, 0,
321 - dest_x, dest_y,
322 - width, height,
323 - clip_region);
325 - _cairo_pattern_fini (&mask.base);
327 - analysis->Release();
328 - delete [] surface;
330 - cairo_surface_destroy (&mask_surface->base);
331 - *remaining_glyphs = 0;
333 - return (cairo_int_status_t)CAIRO_STATUS_SUCCESS;
337 /* cairo_dwrite_scaled_glyph_init helper function bodies */
338 cairo_int_status_t
339 _cairo_dwrite_scaled_font_init_glyph_metrics(cairo_dwrite_scaled_font_t *scaled_font,
340 @@ -906,37 +721,40 @@ cairo_int_status_t
341 return CAIRO_INT_STATUS_SUCCESS;
344 -/* Helper function also stolen from cairo-win32-font.c */
345 +/* Helper function adapted from _compute_mask in cairo-win32-font.c */
347 /* Compute an alpha-mask from a monochrome RGB24 image
349 static cairo_surface_t *
350 -_compute_a8_mask (cairo_win32_surface_t *mask_surface)
351 +_compute_a8_mask (cairo_surface_t *surface)
353 - cairo_image_surface_t *image24 = (cairo_image_surface_t *)mask_surface->image;
354 - cairo_image_surface_t *image8;
355 + cairo_image_surface_t *glyph;
356 + cairo_image_surface_t *mask;
357 int i, j;
359 - if (image24->base.status)
360 - return cairo_surface_reference (&image24->base);
361 + glyph = (cairo_image_surface_t *)cairo_surface_map_to_image (surface, NULL);
362 + if (unlikely (glyph->base.status))
363 + return &glyph->base;
365 - image8 = (cairo_image_surface_t *)cairo_image_surface_create (CAIRO_FORMAT_A8,
366 - image24->width, image24->height);
367 - if (image8->base.status)
368 - return &image8->base;
369 + /* No quality param, just use the non-ClearType path */
371 - for (i = 0; i < image24->height; i++) {
372 - uint32_t *p = (uint32_t *) (image24->data + i * image24->stride);
373 - unsigned char *q = (unsigned char *) (image8->data + i * image8->stride);
374 + /* Compute an alpha-mask by using the green channel of a (presumed monochrome)
375 + * RGB24 image.
376 + */
377 + mask = (cairo_image_surface_t *)
378 + cairo_image_surface_create (CAIRO_FORMAT_A8, glyph->width, glyph->height);
379 + if (likely (mask->base.status == CAIRO_STATUS_SUCCESS)) {
380 + for (i = 0; i < glyph->height; i++) {
381 + uint32_t *p = (uint32_t *) (glyph->data + i * glyph->stride);
382 + uint8_t *q = (uint8_t *) (mask->data + i * mask->stride);
384 - for (j = 0; j < image24->width; j++) {
385 - *q = 255 - ((*p & 0x0000ff00) >> 8);
386 - p++;
387 - q++;
389 + for (j = 0; j < glyph->width; j++)
390 + *q++ = 255 - ((*p++ & 0x0000ff00) >> 8);
394 - return &image8->base;
395 + cairo_surface_unmap_image (surface, &glyph->base);
396 + return &mask->base;
399 cairo_int_status_t
400 @@ -1017,7 +835,7 @@ cairo_int_status_t
402 GdiFlush();
404 - image = _compute_a8_mask (surface);
405 + image = _compute_a8_mask (&surface->base);
406 status = (cairo_int_status_t)image->status;
407 if (status)
408 goto FAIL;
409 @@ -1091,13 +909,6 @@ cairo_dwrite_font_face_create_for_dwrite
412 void
413 -cairo_dwrite_scaled_font_allow_manual_show_glyphs(cairo_scaled_font_t *dwrite_scaled_font, cairo_bool_t allowed)
415 - cairo_dwrite_scaled_font_t *font = reinterpret_cast<cairo_dwrite_scaled_font_t*>(dwrite_scaled_font);
416 - font->manual_show_glyphs_allowed = allowed;
419 -void
420 cairo_dwrite_scaled_font_set_force_GDI_classic(cairo_scaled_font_t *dwrite_scaled_font, cairo_bool_t force)
422 cairo_dwrite_scaled_font_t *font = reinterpret_cast<cairo_dwrite_scaled_font_t*>(dwrite_scaled_font);
423 @@ -1299,20 +1110,11 @@ cairo_int_status_t
425 /* If we have a fallback mask clip set on the dst, we have
426 * to go through the fallback path */
427 - if (clip != NULL) {
428 - if ((dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) == 0) {
429 - cairo_region_t *clip_region;
430 - cairo_int_status_t status;
432 - status = _cairo_clip_get_region (clip, &clip_region);
433 - assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO);
434 - if (status)
435 - return status;
437 - _cairo_win32_surface_set_clip_region (dst, clip_region);
439 - } else {
440 - _cairo_win32_surface_set_clip_region (surface, NULL);
441 + if (!_cairo_surface_is_win32_printing (&dst->base)) {
442 + if (clip != NULL)
443 + _cairo_win32_display_surface_set_clip (to_win32_display_surface (dst), clip);
444 + else
445 + _cairo_win32_display_surface_unset_clip (to_win32_display_surface (dst));
448 /* It is vital that dx values for dxy_buf are calculated from the delta of
449 diff --git a/gfx/cairo/cairo/src/win32/cairo-dwrite-private.h b/gfx/cairo/cairo/src/win32/cairo-dwrite-private.h
450 --- a/gfx/cairo/cairo/src/win32/cairo-dwrite-private.h
451 +++ b/gfx/cairo/cairo/src/win32/cairo-dwrite-private.h
452 @@ -50,7 +50,6 @@ struct _cairo_dwrite_scaled_font {
453 cairo_matrix_t mat_inverse;
454 cairo_antialias_t antialias_mode;
455 DWRITE_MEASURING_MODE measuring_mode;
456 - cairo_bool_t manual_show_glyphs_allowed;
457 enum TextRenderingState {
458 TEXT_RENDERING_UNINITIALIZED,
459 TEXT_RENDERING_NO_CLEARTYPE,
460 diff --git a/gfx/cairo/cairo/src/win32/cairo-win32-font.c b/gfx/cairo/cairo/src/win32/cairo-win32-font.c
461 --- a/gfx/cairo/cairo/src/win32/cairo-win32-font.c
462 +++ b/gfx/cairo/cairo/src/win32/cairo-win32-font.c
463 @@ -286,8 +286,8 @@ static cairo_bool_t
464 version_info.dwMinorVersion >= 1)); /* XP or newer */
467 -static BYTE
468 -_get_system_quality (void)
469 +BYTE
470 +cairo_win32_get_system_text_quality (void)
472 BOOL font_smoothing;
473 UINT smoothing_type;
474 @@ -354,7 +354,7 @@ static cairo_status_t
475 * here is the hint_metrics options.
477 if (options->antialias == CAIRO_ANTIALIAS_DEFAULT)
478 - f->quality = _get_system_quality ();
479 + f->quality = cairo_win32_get_system_text_quality ();
480 else {
481 switch (options->antialias) {
482 case CAIRO_ANTIALIAS_NONE:
483 diff --git a/gfx/cairo/cairo/src/win32/cairo-win32-printing-surface.c b/gfx/cairo/cairo/src/win32/cairo-win32-printing-surface.c
484 --- a/gfx/cairo/cairo/src/win32/cairo-win32-printing-surface.c
485 +++ b/gfx/cairo/cairo/src/win32/cairo-win32-printing-surface.c
486 @@ -244,7 +244,7 @@ static cairo_status_t
487 case CAIRO_PATTERN_TYPE_MESH:
488 default:
489 ASSERT_NOT_REACHED;
490 - break;
491 + return CAIRO_INT_STATUS_UNSUPPORTED;
494 _cairo_pattern_init_for_surface (image_pattern, &image->base);
495 @@ -1808,6 +1808,7 @@ static cairo_int_status_t
496 cairo_solid_pattern_t clear;
497 cairo_composite_rectangles_t extents;
498 cairo_bool_t overlap;
499 + cairo_scaled_font_t *local_scaled_font = NULL;
501 status = _cairo_composite_rectangles_init_for_glyphs (&extents,
502 &surface->win32.base,
503 @@ -1851,6 +1852,13 @@ static cairo_int_status_t
505 #endif
507 +#if CAIRO_HAS_DWRITE_FONT
508 + if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_DWRITE) {
509 + status = _cairo_win32_printing_surface_analyze_operation (surface, op, source, &extents.bounded);
510 + goto cleanup_composite;
512 +#endif
514 /* For non win32 fonts we need to check that each glyph has a
515 * path available. If a path is not available,
516 * _cairo_scaled_glyph_lookup() will return
517 @@ -1890,6 +1898,23 @@ static cairo_int_status_t
518 source = opaque;
521 +#if CAIRO_HAS_DWRITE_FONT
522 + /* For a printer, the dwrite path is not desirable as it goes through the
523 + * bitmap-blitting GDI interop route. Better to create a win32 (GDI) font
524 + * so that ExtTextOut can be used, giving the printer driver the chance
525 + * to do the right thing with the text.
526 + */
527 + if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_DWRITE) {
528 + status = _cairo_dwrite_scaled_font_create_win32_scaled_font (scaled_font, &local_scaled_font);
529 + if (status == CAIRO_STATUS_SUCCESS) {
530 + scaled_font = local_scaled_font;
531 + } else {
532 + /* Reset status; we'll fall back to drawing glyphs as paths */
533 + status = CAIRO_STATUS_SUCCESS;
536 +#endif
538 #if CAIRO_HAS_WIN32_FONT
539 if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_WIN32 &&
540 source->type == CAIRO_PATTERN_TYPE_SOLID)
541 @@ -1948,6 +1973,10 @@ static cairo_int_status_t
543 cleanup_composite:
544 _cairo_composite_rectangles_fini (&extents);
546 + if (local_scaled_font)
547 + cairo_scaled_font_destroy (local_scaled_font);
549 return status;
552 @@ -2181,6 +2210,12 @@ cairo_win32_printing_surface_create (HDC
553 return paginated;
556 +cairo_bool_t
557 +_cairo_surface_is_win32_printing (const cairo_surface_t *surface)
559 + return surface->backend && surface->backend->type == CAIRO_SURFACE_TYPE_WIN32_PRINTING;
562 static const cairo_surface_backend_t cairo_win32_printing_surface_backend = {
563 CAIRO_SURFACE_TYPE_WIN32_PRINTING,
564 _cairo_win32_printing_surface_finish,
565 diff --git a/gfx/cairo/cairo/src/win32/cairo-win32-private.h b/gfx/cairo/cairo/src/win32/cairo-win32-private.h
566 --- a/gfx/cairo/cairo/src/win32/cairo-win32-private.h
567 +++ b/gfx/cairo/cairo/src/win32/cairo-win32-private.h
568 @@ -53,6 +53,8 @@
570 #define WIN32_FONT_LOGICAL_SCALE 32
572 +CAIRO_BEGIN_DECLS
574 /* Surface DC flag values */
575 enum {
576 /* If this is a surface created for printing or not */
577 @@ -199,6 +201,12 @@ const cairo_compositor_t *
578 cairo_status_t
579 _cairo_win32_print_gdi_error (const char *context);
581 +cairo_bool_t
582 +_cairo_surface_is_win32 (const cairo_surface_t *surface);
584 +cairo_bool_t
585 +_cairo_surface_is_win32_printing (const cairo_surface_t *surface);
587 cairo_private void
588 _cairo_win32_display_surface_discard_fallback (cairo_win32_display_surface_t *surface);
590 @@ -245,4 +253,23 @@ cairo_bool_t
591 cairo_bool_t
592 _cairo_win32_scaled_font_is_bitmap (cairo_scaled_font_t *scaled_font);
594 +#ifdef CAIRO_HAS_DWRITE_FONT
596 +cairo_int_status_t
597 +_cairo_dwrite_show_glyphs_on_surface (void *surface,
598 + cairo_operator_t op,
599 + const cairo_pattern_t *source,
600 + cairo_glyph_t *glyphs,
601 + int num_glyphs,
602 + cairo_scaled_font_t *scaled_font,
603 + cairo_clip_t *clip);
605 +cairo_int_status_t
606 +_cairo_dwrite_scaled_font_create_win32_scaled_font (cairo_scaled_font_t *scaled_font,
607 + cairo_scaled_font_t **new_font);
609 +#endif /* CAIRO_HAS_DWRITE_FONT */
611 +CAIRO_END_DECLS
613 #endif /* CAIRO_WIN32_PRIVATE_H */
614 diff --git a/gfx/cairo/cairo/src/win32/cairo-win32-surface.c b/gfx/cairo/cairo/src/win32/cairo-win32-surface.c
615 --- a/gfx/cairo/cairo/src/win32/cairo-win32-surface.c
616 +++ b/gfx/cairo/cairo/src/win32/cairo-win32-surface.c
617 @@ -48,6 +48,7 @@
619 #include "cairoint.h"
621 +#include "cairo-backend-private.h"
622 #include "cairo-default-context-private.h"
623 #include "cairo-error-private.h"
624 #include "cairo-image-surface-private.h"
625 @@ -170,6 +171,48 @@ cairo_win32_surface_get_dc (cairo_surfac
626 return NULL;
629 +HDC
630 +cairo_win32_get_dc_with_clip (cairo_t *cr)
632 + cairo_surface_t *surface = cairo_get_target (cr);
633 + if (cr->backend->type == CAIRO_TYPE_DEFAULT) {
634 + cairo_default_context_t *c = (cairo_default_context_t *) cr;
635 + cairo_clip_t *clip = _cairo_clip_copy (_cairo_gstate_get_clip (c->gstate));
636 + if (_cairo_surface_is_win32 (surface)) {
637 + cairo_win32_display_surface_t *winsurf = (cairo_win32_display_surface_t *) surface;
639 + _cairo_win32_display_surface_set_clip (winsurf, clip);
641 + _cairo_clip_destroy (clip);
642 + return winsurf->win32.dc;
645 + if (_cairo_surface_is_paginated (surface)) {
646 + cairo_surface_t *target;
648 + target = _cairo_paginated_surface_get_target (surface);
650 +#ifndef CAIRO_OMIT_WIN32_PRINTING
651 + if (_cairo_surface_is_win32_printing (target)) {
652 + cairo_status_t status;
653 + cairo_win32_printing_surface_t *psurf = (cairo_win32_printing_surface_t *) target;
655 + status = _cairo_surface_clipper_set_clip (&psurf->clipper, clip);
657 + _cairo_clip_destroy (clip);
659 + if (status)
660 + return NULL;
662 + return psurf->win32.dc;
664 +#endif
666 + _cairo_clip_destroy (clip);
668 + return NULL;
672 * _cairo_surface_is_win32:
673 * @surface: a #cairo_surface_t
674 @@ -178,7 +221,7 @@ cairo_win32_surface_get_dc (cairo_surfac
676 * Return value: %TRUE if the surface is an win32 surface
678 -static inline cairo_bool_t
679 +cairo_bool_t
680 _cairo_surface_is_win32 (const cairo_surface_t *surface)
682 /* _cairo_surface_nil sets a NULL backend so be safe */
683 @@ -219,6 +262,16 @@ cairo_int_status_t
684 cairo_scaled_font_t *scaled_font,
685 cairo_bool_t glyph_indexing)
687 +#if CAIRO_HAS_DWRITE_FONT
688 + if (scaled_font->backend->type == CAIRO_FONT_TYPE_DWRITE) {
689 + if (!glyph_indexing) return CAIRO_INT_STATUS_UNSUPPORTED;
691 + // FIXME: fake values for params that aren't currently passed in here
692 + cairo_operator_t op = CAIRO_OPERATOR_SOURCE;
693 + cairo_clip_t *clip = NULL;
694 + return _cairo_dwrite_show_glyphs_on_surface (dst, op, source, glyphs, num_glyphs, scaled_font, clip /* , glyph_indexing */ );
696 +#endif
697 #if CAIRO_HAS_WIN32_FONT
698 WORD glyph_buf_stack[STACK_GLYPH_SIZE];
699 WORD *glyph_buf = glyph_buf_stack;
700 @@ -335,3 +388,18 @@ cairo_int_status_t
701 #endif
703 #undef STACK_GLYPH_SIZE
705 +cairo_status_t
706 +cairo_win32_surface_get_size (const cairo_surface_t *surface, int *width, int *height)
708 + if (surface->type != CAIRO_SURFACE_TYPE_WIN32)
709 + return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
711 + const cairo_win32_surface_t *winsurface = (const cairo_win32_surface_t *) surface;
713 + *width = winsurface->extents.width;
714 + *height = winsurface->extents.height;
716 + return CAIRO_STATUS_SUCCESS;