1 /* cairo - a vector graphics library with display and print output
2 *
3 * Copyright © 2005 Red Hat, Inc
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it either under the terms of the GNU Lesser General Public
7 * License version 2.1 as published by the Free Software Foundation
8 * (the "LGPL") or, at your option, under the terms of the Mozilla
9 * Public License Version 1.1 (the "MPL"). If you do not alter this
10 * notice, a recipient may use your version of this file under either
11 * the MPL or the LGPL.
12 *
13 * You should have received a copy of the LGPL along with this library
14 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16 * You should have received a copy of the MPL along with this library
17 * in the file COPYING-MPL-1.1
18 *
19 * The contents of this file are subject to the Mozilla Public License
20 * Version 1.1 (the "License"); you may not use this file except in
21 * compliance with the License. You may obtain a copy of the License at
22 * http://www.mozilla.org/MPL/
23 *
24 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26 * the specific language governing rights and limitations.
27 *
28 * The Original Code is the cairo graphics library.
29 *
30 * The Initial Developer of the Original Code is Red Hat, Inc.
31 *
32 * Contributor(s):
33 * Owen Taylor <otaylor@redhat.com>
34 */
35
36 #ifndef CAIRO_WIN32_PRIVATE_H
37 #define CAIRO_WIN32_PRIVATE_H
38
39 #include "cairo-win32.h"
40
41 #include "cairoint.h"
42
43 #include "cairo-device-private.h"
44 #include "cairo-surface-clipper-private.h"
45 #include "cairo-surface-private.h"
46
47 #ifndef SHADEBLENDCAPS
48 #define SHADEBLENDCAPS 120
49 #endif
50 #ifndef SB_NONE
51 #define SB_NONE 0
52 #endif
53
54 #define WIN32_FONT_LOGICAL_SCALE 32
55
56 CAIRO_BEGIN_DECLS
57
58 /* Surface DC flag values */
59 enum {
60 /* If this is a surface created for printing or not */
61 CAIRO_WIN32_SURFACE_FOR_PRINTING = (1<<0),
62
63 /* Whether the DC is a display DC or not */
64 CAIRO_WIN32_SURFACE_IS_DISPLAY = (1<<1),
65
66 /* Whether we can use BitBlt with this surface */
67 CAIRO_WIN32_SURFACE_CAN_BITBLT = (1<<2),
68
69 /* Whether we can use AlphaBlend with this surface */
70 CAIRO_WIN32_SURFACE_CAN_ALPHABLEND = (1<<3),
71
72 /* Whether we can use StretchBlt with this surface */
73 CAIRO_WIN32_SURFACE_CAN_STRETCHBLT = (1<<4),
74
75 /* Whether we can use StretchDIBits with this surface */
76 CAIRO_WIN32_SURFACE_CAN_STRETCHDIB = (1<<5),
77
78 /* Whether we can use GradientFill rectangles with this surface */
79 CAIRO_WIN32_SURFACE_CAN_RECT_GRADIENT = (1<<6),
80
81 /* Whether we can use the CHECKJPEGFORMAT escape function */
82 CAIRO_WIN32_SURFACE_CAN_CHECK_JPEG = (1<<7),
83
84 /* Whether we can use the CHECKPNGFORMAT escape function */
85 CAIRO_WIN32_SURFACE_CAN_CHECK_PNG = (1<<8),
86
87 /* Whether we can use gdi drawing with solid rgb brush with this surface */
88 CAIRO_WIN32_SURFACE_CAN_RGB_BRUSH = (1<<9),
89 };
90
91 typedef struct _cairo_win32_surface {
92 cairo_surface_t base;
93
94 cairo_format_t format;
95 HDC dc;
96
97 /* Surface DC flags */
98 unsigned flags;
99
100 /* We use the x and y parts of extents for situations where
101 * we're not supposed to draw to the entire surface.
102 * For example, during a paint event a program will get
103 * a DC that has been clipped to the dirty region.
104 * A cairo surface constructed for that DC will have extents
105 * that match bounds of the clipped region.
106 */
107 cairo_rectangle_int_t extents;
108
109 /* Offset added to extents, used when the extents start with a negative
110 * offset, which can occur on Windows for, and only for, desktop DC. This
111 * occurs when you have multiple monitors, and at least one monitor
112 * extends to the left, or above, the primaty monitor. The primary
113 * monitor on Windows always starts with offset (0,0), and any other points
114 * to the left, or above, have negative offsets. So the 'desktop DC' is
115 * in fact a 'virtual desktop' which can start with extents in the negative
116 * range.
117 *
118 * Why use new variables, and not the device transform? Simply because since
119 * the device transform functions are exposed, a lot of 3rd party libraries
120 * simply overwrite those, disregarding the prior content, instead of actually
121 * adding the offset. GTK for example simply resets the device transform of the
122 * desktop cairo surface to zero. So make some private member variables for
123 * this, which will not be fiddled with externally.
124 */
125 int x_ofs, y_ofs;
126 } cairo_win32_surface_t;
127 #define to_win32_surface(S) ((cairo_win32_surface_t *)(S))
128
129 typedef struct _cairo_win32_display_surface {
130 cairo_win32_surface_t win32;
131
132 /* We create off-screen surfaces as DIBs or DDBs, based on what we created
133 * originally */
134 HBITMAP bitmap;
135 cairo_bool_t is_dib;
136
137 /* Used to save the initial 1x1 monochrome bitmap for the DC to
138 * select back into the DC before deleting the DC and our
139 * bitmap. For Windows XP, this doesn't seem to be necessary
140 * ... we can just delete the DC and that automatically unselects
141 * our bitmap. But it's standard practice so apparently is needed
142 * on some versions of Windows.
143 */
144 HBITMAP saved_dc_bitmap;
145 cairo_surface_t *image;
146 cairo_surface_t *fallback;
147
148 HRGN initial_clip_rgn;
149 cairo_bool_t had_simple_clip;
150 } cairo_win32_display_surface_t;
151 #define to_win32_display_surface(S) ((cairo_win32_display_surface_t *)(S))
152
153 typedef struct _cairo_win32_printing_surface {
154 cairo_win32_surface_t win32;
155
156 cairo_surface_clipper_t clipper;
157
158 cairo_paginated_mode_t paginated_mode;
159 cairo_content_t content;
160 cairo_bool_t path_empty;
161 cairo_bool_t has_ctm;
162 cairo_matrix_t ctm;
163 cairo_bool_t has_gdi_ctm;
164 cairo_matrix_t gdi_ctm;
165 cairo_bool_t extents_valid;
166 HBRUSH brush, old_brush;
167 cairo_scaled_font_subsets_t *font_subsets;
168 } cairo_win32_printing_surface_t;
169 #define to_win32_printing_surface(S) ((cairo_win32_printing_surface_t *)(S))
170
171 typedef BOOL (WINAPI *cairo_win32_alpha_blend_func_t) (HDC hdcDest,
172 int nXOriginDest,
173 int nYOriginDest,
174 int nWidthDest,
175 int hHeightDest,
176 HDC hdcSrc,
177 int nXOriginSrc,
178 int nYOriginSrc,
179 int nWidthSrc,
180 int nHeightSrc,
181 BLENDFUNCTION blendFunction);
182
183 typedef struct _cairo_win32_device {
184 cairo_device_t base;
185
186 HMODULE msimg32_dll;
187
188 const cairo_compositor_t *compositor;
189
190 cairo_win32_alpha_blend_func_t alpha_blend;
191 } cairo_win32_device_t;
192 #define to_win32_device(D) ((cairo_win32_device_t *)(D))
193 #define to_win32_device_from_surface(S) to_win32_device(((cairo_surface_t *)(S))->device)
194
195 cairo_private cairo_device_t *
196 _cairo_win32_device_get (void);
197
198 const cairo_compositor_t *
199 _cairo_win32_gdi_compositor_get (void);
200
201 cairo_status_t
202 _cairo_win32_print_gdi_error (const char *context);
203
204 cairo_bool_t
205 _cairo_surface_is_win32 (const cairo_surface_t *surface);
206
207 cairo_bool_t
208 _cairo_surface_is_win32_printing (const cairo_surface_t *surface);
209
210 cairo_private void
211 _cairo_win32_display_surface_discard_fallback (cairo_win32_display_surface_t *surface);
212
213 cairo_bool_t
214 _cairo_win32_surface_get_extents (void *abstract_surface,
215 cairo_rectangle_int_t *rectangle);
216
217 uint32_t
218 _cairo_win32_flags_for_dc (HDC dc, cairo_format_t format);
219
220 cairo_int_status_t
221 _cairo_win32_surface_emit_glyphs (cairo_win32_surface_t *dst,
222 const cairo_pattern_t *source,
223 cairo_glyph_t *glyphs,
224 int num_glyphs,
225 cairo_scaled_font_t *scaled_font,
226 cairo_bool_t glyph_indexing);
227
228 static inline void
_cairo_matrix_to_win32_xform(const cairo_matrix_t * m,XFORM * xform)229 _cairo_matrix_to_win32_xform (const cairo_matrix_t *m,
230 XFORM *xform)
231 {
232 xform->eM11 = (FLOAT) m->xx;
233 xform->eM21 = (FLOAT) m->xy;
234 xform->eM12 = (FLOAT) m->yx;
235 xform->eM22 = (FLOAT) m->yy;
236 xform->eDx = (FLOAT) m->x0;
237 xform->eDy = (FLOAT) m->y0;
238 }
239
240 cairo_status_t
241 _cairo_win32_display_surface_set_clip (cairo_win32_display_surface_t *surface,
242 cairo_clip_t *clip);
243
244 void
245 _cairo_win32_display_surface_unset_clip (cairo_win32_display_surface_t *surface);
246
247 void
248 _cairo_win32_debug_dump_hrgn (HRGN rgn, char *header);
249
250 cairo_bool_t
251 _cairo_win32_scaled_font_is_type1 (cairo_scaled_font_t *scaled_font);
252
253 cairo_bool_t
254 _cairo_win32_scaled_font_is_bitmap (cairo_scaled_font_t *scaled_font);
255
256 #ifdef CAIRO_HAS_DWRITE_FONT
257
258 cairo_int_status_t
259 _cairo_dwrite_show_glyphs_on_surface (void *surface,
260 cairo_operator_t op,
261 const cairo_pattern_t *source,
262 cairo_glyph_t *glyphs,
263 int num_glyphs,
264 cairo_scaled_font_t *scaled_font,
265 cairo_clip_t *clip);
266
267 cairo_int_status_t
268 _cairo_dwrite_scaled_font_create_win32_scaled_font (cairo_scaled_font_t *scaled_font,
269 cairo_scaled_font_t **new_font);
270
271 #endif /* CAIRO_HAS_DWRITE_FONT */
272
273 CAIRO_END_DECLS
274
275 #endif /* CAIRO_WIN32_PRIVATE_H */
276