gdi32: Keep track of the combined clip region.
[wine.git] / dlls / gdi32 / dibdrv / dc.c
blob9e971775b4ebc57c37039c4cc4edc5ca7e62c21d
1 /*
2 * DIB driver initialization and DC functions.
4 * Copyright 2011 Huw Davies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <assert.h>
23 #include "gdi_private.h"
24 #include "dibdrv.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(dib);
30 /***********************************************************************
31 * dibdrv_DeleteDC
33 static BOOL CDECL dibdrv_DeleteDC( PHYSDEV dev )
35 dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
36 TRACE("(%p)\n", dev);
37 DeleteObject(pdev->clip);
38 return 0;
41 static void calc_shift_and_len(DWORD mask, int *shift, int *len)
43 int s, l;
45 if(!mask)
47 *shift = *len = 0;
48 return;
51 s = 0;
52 while ((mask & 1) == 0)
54 mask >>= 1;
55 s++;
57 l = 0;
58 while ((mask & 1) == 1)
60 mask >>= 1;
61 l++;
63 *shift = s;
64 *len = l;
67 static void init_bit_fields(dib_info *dib, const DWORD *bit_fields)
69 dib->red_mask = bit_fields[0];
70 dib->green_mask = bit_fields[1];
71 dib->blue_mask = bit_fields[2];
72 calc_shift_and_len(dib->red_mask, &dib->red_shift, &dib->red_len);
73 calc_shift_and_len(dib->green_mask, &dib->green_shift, &dib->green_len);
74 calc_shift_and_len(dib->blue_mask, &dib->blue_shift, &dib->blue_len);
77 static BOOL init_dib(dib_info *dib, const BITMAPINFOHEADER *bi, const DWORD *bit_fields, void *bits)
79 dib->bit_count = bi->biBitCount;
80 dib->width = bi->biWidth;
81 dib->height = bi->biHeight;
82 dib->stride = ((dib->width * dib->bit_count + 31) >> 3) & ~3;
83 dib->bits = bits;
85 if(dib->height < 0) /* top-down */
87 dib->height = -dib->height;
89 else /* bottom-up */
91 /* bits always points to the top-left corner and the stride is -ve */
92 dib->bits = (BYTE*)dib->bits + (dib->height - 1) * dib->stride;
93 dib->stride = -dib->stride;
96 dib->funcs = &funcs_null;
98 switch(dib->bit_count)
100 case 32:
101 if(bi->biCompression == BI_RGB)
102 dib->funcs = &funcs_8888;
103 else
105 init_bit_fields(dib, bit_fields);
106 if(dib->red_mask == 0xff0000 && dib->green_mask == 0x00ff00 && dib->blue_mask == 0x0000ff)
107 dib->funcs = &funcs_8888;
108 else
109 dib->funcs = &funcs_32;
111 break;
113 default:
114 TRACE("bpp %d not supported, will forward to graphics driver.\n", dib->bit_count);
115 return FALSE;
118 return TRUE;
121 /***********************************************************************
122 * dibdrv_SelectBitmap
124 static HBITMAP CDECL dibdrv_SelectBitmap( PHYSDEV dev, HBITMAP bitmap )
126 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectBitmap );
127 dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
128 BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP );
129 TRACE("(%p, %p)\n", dev, bitmap);
131 if (!bmp) return 0;
132 assert(bmp->dib);
134 pdev->clip = CreateRectRgn(0, 0, 0, 0);
135 pdev->defer = 0;
137 if(!init_dib(&pdev->dib, &bmp->dib->dsBmih, bmp->dib->dsBitfields, bmp->dib->dsBm.bmBits))
138 pdev->defer |= DEFER_FORMAT;
140 GDI_ReleaseObj( bitmap );
142 return next->funcs->pSelectBitmap( next, bitmap );
145 /***********************************************************************
146 * dibdrv_SetDeviceClipping
148 static void CDECL dibdrv_SetDeviceClipping( PHYSDEV dev, HRGN vis_rgn, HRGN clip_rgn )
150 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetDeviceClipping );
151 dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
152 TRACE("(%p, %p, %p)\n", dev, vis_rgn, clip_rgn);
154 CombineRgn( pdev->clip, vis_rgn, clip_rgn, clip_rgn ? RGN_AND : RGN_COPY );
155 return next->funcs->pSetDeviceClipping( next, vis_rgn, clip_rgn);
158 /***********************************************************************
159 * dibdrv_SetROP2
161 static INT CDECL dibdrv_SetROP2( PHYSDEV dev, INT rop )
163 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetROP2 );
164 dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
166 calc_and_xor_masks(rop, pdev->pen_color, &pdev->pen_and, &pdev->pen_xor);
167 update_brush_rop(pdev, rop);
169 return next->funcs->pSetROP2( next, rop );
172 const DC_FUNCTIONS dib_driver =
174 NULL, /* pAbortDoc */
175 NULL, /* pAbortPath */
176 NULL, /* pAlphaBlend */
177 NULL, /* pAngleArc */
178 NULL, /* pArc */
179 NULL, /* pArcTo */
180 NULL, /* pBeginPath */
181 NULL, /* pChoosePixelFormat */
182 NULL, /* pChord */
183 NULL, /* pCloseFigure */
184 NULL, /* pCreateBitmap */
185 NULL, /* pCreateDC */
186 NULL, /* pCreateDIBSection */
187 NULL, /* pDeleteBitmap */
188 dibdrv_DeleteDC, /* pDeleteDC */
189 NULL, /* pDeleteObject */
190 NULL, /* pDescribePixelFormat */
191 NULL, /* pDeviceCapabilities */
192 NULL, /* pEllipse */
193 NULL, /* pEndDoc */
194 NULL, /* pEndPage */
195 NULL, /* pEndPath */
196 NULL, /* pEnumDeviceFonts */
197 NULL, /* pEnumICMProfiles */
198 NULL, /* pExcludeClipRect */
199 NULL, /* pExtDeviceMode */
200 NULL, /* pExtEscape */
201 NULL, /* pExtFloodFill */
202 NULL, /* pExtSelectClipRgn */
203 NULL, /* pExtTextOut */
204 NULL, /* pFillPath */
205 NULL, /* pFillRgn */
206 NULL, /* pFlattenPath */
207 NULL, /* pFrameRgn */
208 NULL, /* pGdiComment */
209 NULL, /* pGetBitmapBits */
210 NULL, /* pGetCharWidth */
211 NULL, /* pGetDIBits */
212 NULL, /* pGetDeviceCaps */
213 NULL, /* pGetDeviceGammaRamp */
214 NULL, /* pGetICMProfile */
215 NULL, /* pGetNearestColor */
216 NULL, /* pGetPixel */
217 NULL, /* pGetPixelFormat */
218 NULL, /* pGetSystemPaletteEntries */
219 NULL, /* pGetTextExtentExPoint */
220 NULL, /* pGetTextMetrics */
221 NULL, /* pIntersectClipRect */
222 NULL, /* pInvertRgn */
223 dibdrv_LineTo, /* pLineTo */
224 NULL, /* pModifyWorldTransform */
225 NULL, /* pMoveTo */
226 NULL, /* pOffsetClipRgn */
227 NULL, /* pOffsetViewportOrg */
228 NULL, /* pOffsetWindowOrg */
229 NULL, /* pPaintRgn */
230 dibdrv_PatBlt, /* pPatBlt */
231 NULL, /* pPie */
232 NULL, /* pPolyBezier */
233 NULL, /* pPolyBezierTo */
234 NULL, /* pPolyDraw */
235 NULL, /* pPolyPolygon */
236 NULL, /* pPolyPolyline */
237 NULL, /* pPolygon */
238 NULL, /* pPolyline */
239 NULL, /* pPolylineTo */
240 NULL, /* pRealizeDefaultPalette */
241 NULL, /* pRealizePalette */
242 NULL, /* pRectangle */
243 NULL, /* pResetDC */
244 NULL, /* pRestoreDC */
245 NULL, /* pRoundRect */
246 NULL, /* pSaveDC */
247 NULL, /* pScaleViewportExt */
248 NULL, /* pScaleWindowExt */
249 dibdrv_SelectBitmap, /* pSelectBitmap */
250 dibdrv_SelectBrush, /* pSelectBrush */
251 NULL, /* pSelectClipPath */
252 NULL, /* pSelectFont */
253 NULL, /* pSelectPalette */
254 dibdrv_SelectPen, /* pSelectPen */
255 NULL, /* pSetArcDirection */
256 NULL, /* pSetBitmapBits */
257 NULL, /* pSetBkColor */
258 NULL, /* pSetBkMode */
259 dibdrv_SetDCBrushColor, /* pSetDCBrushColor */
260 dibdrv_SetDCPenColor, /* pSetDCPenColor */
261 NULL, /* pSetDIBColorTable */
262 NULL, /* pSetDIBits */
263 NULL, /* pSetDIBitsToDevice */
264 dibdrv_SetDeviceClipping, /* pSetDeviceClipping */
265 NULL, /* pSetDeviceGammaRamp */
266 NULL, /* pSetLayout */
267 NULL, /* pSetMapMode */
268 NULL, /* pSetMapperFlags */
269 NULL, /* pSetPixel */
270 NULL, /* pSetPixelFormat */
271 NULL, /* pSetPolyFillMode */
272 dibdrv_SetROP2, /* pSetROP2 */
273 NULL, /* pSetRelAbs */
274 NULL, /* pSetStretchBltMode */
275 NULL, /* pSetTextAlign */
276 NULL, /* pSetTextCharacterExtra */
277 NULL, /* pSetTextColor */
278 NULL, /* pSetTextJustification */
279 NULL, /* pSetViewportExt */
280 NULL, /* pSetViewportOrg */
281 NULL, /* pSetWindowExt */
282 NULL, /* pSetWindowOrg */
283 NULL, /* pSetWorldTransform */
284 NULL, /* pStartDoc */
285 NULL, /* pStartPage */
286 NULL, /* pStretchBlt */
287 NULL, /* pStretchDIBits */
288 NULL, /* pStrokeAndFillPath */
289 NULL, /* pStrokePath */
290 NULL, /* pSwapBuffers */
291 NULL, /* pUnrealizePalette */
292 NULL, /* pWidenPath */
293 NULL, /* pwglCopyContext */
294 NULL, /* pwglCreateContext */
295 NULL, /* pwglCreateContextAttribsARB */
296 NULL, /* pwglDeleteContext */
297 NULL, /* pwglGetProcAddress */
298 NULL, /* pwglGetPbufferDCARB */
299 NULL, /* pwglMakeCurrent */
300 NULL, /* pwglMakeContextCurrentARB */
301 NULL, /* pwglSetPixelFormatWINE */
302 NULL, /* pwglShareLists */
303 NULL, /* pwglUseFontBitmapsA */
304 NULL /* pwglUseFontBitmapsW */