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