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 /* Surface DC flag values */
57 enum {
58     /* If this is a surface created for printing or not */
59     CAIRO_WIN32_SURFACE_FOR_PRINTING = (1<<0),
60 
61     /* Whether the DC is a display DC or not */
62     CAIRO_WIN32_SURFACE_IS_DISPLAY = (1<<1),
63 
64     /* Whether we can use BitBlt with this surface */
65     CAIRO_WIN32_SURFACE_CAN_BITBLT = (1<<2),
66 
67     /* Whether we can use AlphaBlend with this surface */
68     CAIRO_WIN32_SURFACE_CAN_ALPHABLEND = (1<<3),
69 
70     /* Whether we can use StretchBlt with this surface */
71     CAIRO_WIN32_SURFACE_CAN_STRETCHBLT = (1<<4),
72 
73     /* Whether we can use StretchDIBits with this surface */
74     CAIRO_WIN32_SURFACE_CAN_STRETCHDIB = (1<<5),
75 
76     /* Whether we can use GradientFill rectangles with this surface */
77     CAIRO_WIN32_SURFACE_CAN_RECT_GRADIENT = (1<<6),
78 
79     /* Whether we can use the CHECKJPEGFORMAT escape function */
80     CAIRO_WIN32_SURFACE_CAN_CHECK_JPEG = (1<<7),
81 
82     /* Whether we can use the CHECKPNGFORMAT escape function */
83     CAIRO_WIN32_SURFACE_CAN_CHECK_PNG = (1<<8),
84 
85     /* Whether we can use gdi drawing with solid rgb brush with this surface */
86     CAIRO_WIN32_SURFACE_CAN_RGB_BRUSH = (1<<9),
87 };
88 
89 typedef struct _cairo_win32_surface {
90     cairo_surface_t base;
91 
92     cairo_format_t format;
93     HDC dc;
94 
95     /* Surface DC flags */
96     unsigned flags;
97 
98     /* We use the x and y parts of extents for situations where
99      * we're not supposed to draw to the entire surface.
100      * For example, during a paint event a program will get
101      * a DC that has been clipped to the dirty region.
102      * A cairo surface constructed for that DC will have extents
103      * that match bounds of the clipped region.
104      */
105     cairo_rectangle_int_t extents;
106 
107     /* Offset added to extents, used when the extents start with a negative
108      * offset, which can occur on Windows for, and only for, desktop DC.  This
109      * occurs when you have multiple monitors, and at least one monitor
110      * extends to the left, or above, the primaty monitor.  The primary
111      * monitor on Windows always starts with offset (0,0), and any other points
112      * to the left, or above, have negative offsets.  So the 'desktop DC' is
113      * in fact a 'virtual desktop' which can start with extents in the negative
114      * range.
115      *
116      * Why use new variables, and not the device transform?  Simply because since
117      * the device transform functions are exposed, a lot of 3rd party libraries
118      * simply overwrite those, disregarding the prior content, instead of actually
119      * adding the offset.  GTK for example simply resets the device transform of the
120      * desktop cairo surface to zero.  So make some private member variables for
121      * this, which will not be fiddled with externally.
122      */
123     int x_ofs, y_ofs;
124 } cairo_win32_surface_t;
125 #define to_win32_surface(S) ((cairo_win32_surface_t *)(S))
126 
127 typedef struct _cairo_win32_display_surface {
128     cairo_win32_surface_t win32;
129 
130     /* We create off-screen surfaces as DIBs or DDBs, based on what we created
131      * originally */
132     HBITMAP bitmap;
133     cairo_bool_t is_dib;
134 
135     /* Used to save the initial 1x1 monochrome bitmap for the DC to
136      * select back into the DC before deleting the DC and our
137      * bitmap. For Windows XP, this doesn't seem to be necessary
138      * ... we can just delete the DC and that automatically unselects
139      * our bitmap. But it's standard practice so apparently is needed
140      * on some versions of Windows.
141      */
142     HBITMAP saved_dc_bitmap;
143     cairo_surface_t *image;
144     cairo_surface_t *fallback;
145 
146     HRGN initial_clip_rgn;
147     cairo_bool_t had_simple_clip;
148 } cairo_win32_display_surface_t;
149 #define to_win32_display_surface(S) ((cairo_win32_display_surface_t *)(S))
150 
151 typedef struct _cairo_win32_printing_surface {
152     cairo_win32_surface_t win32;
153 
154     cairo_surface_clipper_t clipper;
155 
156     cairo_paginated_mode_t paginated_mode;
157     cairo_content_t content;
158     cairo_bool_t path_empty;
159     cairo_bool_t has_ctm;
160     cairo_matrix_t ctm;
161     cairo_bool_t has_gdi_ctm;
162     cairo_matrix_t gdi_ctm;
163     cairo_bool_t extents_valid;
164     HBRUSH brush, old_brush;
165     cairo_scaled_font_subsets_t *font_subsets;
166 } cairo_win32_printing_surface_t;
167 #define to_win32_printing_surface(S) ((cairo_win32_printing_surface_t *)(S))
168 
169 typedef BOOL (WINAPI *cairo_win32_alpha_blend_func_t) (HDC hdcDest,
170 						       int nXOriginDest,
171 						       int nYOriginDest,
172 						       int nWidthDest,
173 						       int hHeightDest,
174 						       HDC hdcSrc,
175 						       int nXOriginSrc,
176 						       int nYOriginSrc,
177 						       int nWidthSrc,
178 						       int nHeightSrc,
179 						       BLENDFUNCTION blendFunction);
180 
181 typedef struct _cairo_win32_device {
182     cairo_device_t base;
183 
184     HMODULE msimg32_dll;
185 
186     const cairo_compositor_t *compositor;
187 
188     cairo_win32_alpha_blend_func_t alpha_blend;
189 } cairo_win32_device_t;
190 #define to_win32_device(D) ((cairo_win32_device_t *)(D))
191 #define to_win32_device_from_surface(S) to_win32_device(((cairo_surface_t *)(S))->device)
192 
193 cairo_private cairo_device_t *
194 _cairo_win32_device_get (void);
195 
196 const cairo_compositor_t *
197 _cairo_win32_gdi_compositor_get (void);
198 
199 cairo_status_t
200 _cairo_win32_print_gdi_error (const char *context);
201 
202 cairo_private void
203 _cairo_win32_display_surface_discard_fallback (cairo_win32_display_surface_t *surface);
204 
205 cairo_bool_t
206 _cairo_win32_surface_get_extents (void			  *abstract_surface,
207 				  cairo_rectangle_int_t   *rectangle);
208 
209 uint32_t
210 _cairo_win32_flags_for_dc (HDC dc, cairo_format_t format);
211 
212 cairo_int_status_t
213 _cairo_win32_surface_emit_glyphs (cairo_win32_surface_t *dst,
214 				  const cairo_pattern_t *source,
215 				  cairo_glyph_t	 *glyphs,
216 				  int			  num_glyphs,
217 				  cairo_scaled_font_t	 *scaled_font,
218 				  cairo_bool_t		  glyph_indexing);
219 
220 static inline void
_cairo_matrix_to_win32_xform(const cairo_matrix_t * m,XFORM * xform)221 _cairo_matrix_to_win32_xform (const cairo_matrix_t *m,
222 			      XFORM *xform)
223 {
224     xform->eM11 = (FLOAT) m->xx;
225     xform->eM21 = (FLOAT) m->xy;
226     xform->eM12 = (FLOAT) m->yx;
227     xform->eM22 = (FLOAT) m->yy;
228     xform->eDx = (FLOAT) m->x0;
229     xform->eDy = (FLOAT) m->y0;
230 }
231 
232 cairo_status_t
233 _cairo_win32_display_surface_set_clip (cairo_win32_display_surface_t *surface,
234 				       cairo_clip_t *clip);
235 
236 void
237 _cairo_win32_display_surface_unset_clip (cairo_win32_display_surface_t *surface);
238 
239 void
240 _cairo_win32_debug_dump_hrgn (HRGN rgn, char *header);
241 
242 cairo_bool_t
243 _cairo_win32_scaled_font_is_type1 (cairo_scaled_font_t *scaled_font);
244 
245 cairo_bool_t
246 _cairo_win32_scaled_font_is_bitmap (cairo_scaled_font_t *scaled_font);
247 
248 #endif /* CAIRO_WIN32_PRIVATE_H */
249