2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI BitBlt Functions
5 * FILE: subsys/win32k/eng/bitblt.c
6 * PROGRAMER: Jason Filby
11 #include <ddk/winddi.h>
12 #include <ddk/ntddk.h>
13 #include <ntos/minmax.h>
17 #include "../dib/dib.h"
19 #include <include/mouse.h>
20 #include <include/object.h>
21 #include <include/dib.h>
22 #include <include/surface.h>
23 #include <include/copybits.h>
24 #include <include/inteng.h>
27 #include <win32k/debug1.h>
29 BOOL EngIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2)
31 static const RECTL rclEmpty = { 0, 0, 0, 0 };
33 prcDst->left = max(prcSrc1->left, prcSrc2->left);
34 prcDst->right = min(prcSrc1->right, prcSrc2->right);
36 if (prcDst->left < prcDst->right)
38 prcDst->top = max(prcSrc1->top, prcSrc2->top);
39 prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
41 if (prcDst->top < prcDst->bottom) return(TRUE);
50 BltMask(SURFOBJ *Dest, PSURFGDI DestGDI, SURFOBJ *Mask,
51 RECTL *DestRect, POINTL *MaskPoint, BRUSHOBJ* Brush,
54 LONG i, j, dx, dy, c8;
56 static BYTE maskbit[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
58 dx = DestRect->right - DestRect->left;
59 dy = DestRect->bottom - DestRect->top;
64 for (j = 0; j < dy; j++)
68 for (i = 0; i < dx; i++)
70 if (0 != (*lMask & maskbit[c8]))
72 DestGDI->DIB_PutPixel(Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
81 tMask += Mask->lDelta;
92 BltPatCopy(SURFOBJ *Dest, PSURFGDI DestGDI, SURFOBJ *Mask,
93 RECTL *DestRect, POINTL *MaskPoint, BRUSHOBJ* Brush,
96 // These functions are assigned if we're working with a DIB
97 // The assigned functions depend on the bitsPerPixel of the DIB
101 LineWidth = DestRect->right - DestRect->left;
102 for (y = DestRect->top; y < DestRect->bottom; y++)
104 DestGDI->DIB_HLine(Dest, DestRect->left, DestRect->right, y, Brush->iSolidColor);
113 EngBitBlt(SURFOBJ *DestObj,
117 XLATEOBJ *ColorTranslation,
131 PSURFGDI OutputGDI, InputGDI;
136 INTENG_ENTER_LEAVE EnterLeaveSource;
137 INTENG_ENTER_LEAVE EnterLeaveDest;
141 /* Check for degenerate case: if height or width of DestRect is 0 pixels there's
143 if (DestRect->right == DestRect->left || DestRect->bottom == DestRect->top)
148 if (NULL != SourcePoint)
150 InputRect.left = SourcePoint->x;
151 InputRect.right = SourcePoint->x + (DestRect->right - DestRect->left);
152 InputRect.top = SourcePoint->y;
153 InputRect.bottom = SourcePoint->y + (DestRect->bottom - DestRect->top);
158 InputRect.right = DestRect->right - DestRect->left;
160 InputRect.bottom = DestRect->bottom - DestRect->top;
163 if (! IntEngEnter(&EnterLeaveSource, SourceObj, &InputRect, TRUE, &Translate, &InputObj))
168 if (NULL != SourcePoint)
170 InputPoint.x = SourcePoint->x + Translate.x;
171 InputPoint.y = SourcePoint->y + Translate.y;
179 if (NULL != InputObj)
181 InputGDI = (PSURFGDI) AccessInternalObjectFromUserObject(InputObj);
184 OutputRect = *DestRect;
186 if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate, &OutputObj))
188 IntEngLeave(&EnterLeaveSource);
192 OutputRect.left = DestRect->left + Translate.x;
193 OutputRect.right = DestRect->right + Translate.x;
194 OutputRect.top = DestRect->top + Translate.y;
195 OutputRect.bottom = DestRect->bottom + Translate.y;
198 if (NULL != OutputObj)
200 OutputGDI = (PSURFGDI)AccessInternalObjectFromUserObject(OutputObj);
203 /* The code currently assumes there will be a source bitmap. This is not true when, for example, using this function to
204 * paint a brush pattern on the destination. */
205 if (NULL == InputObj && 0xaacc != rop4 && PATCOPY != rop4)
207 DbgPrint("EngBitBlt: A source is currently required, even though not all operations require one (FIXME)\n");
211 // Determine clipping type
212 if (ClipRegion == (CLIPOBJ *) NULL)
214 clippingType = DC_TRIVIAL;
216 clippingType = ClipRegion->iDComplexity;
221 ret = BltMask(OutputObj, OutputGDI, Mask, &OutputRect, MaskOrigin, Brush, BrushOrigin);
222 IntEngLeave(&EnterLeaveDest);
223 IntEngLeave(&EnterLeaveSource);
225 } else if (PATCOPY == rop4) {
226 ret = BltPatCopy(OutputObj, OutputGDI, Mask, &OutputRect, MaskOrigin, Brush, BrushOrigin);
227 IntEngLeave(&EnterLeaveDest);
228 IntEngLeave(&EnterLeaveSource);
233 // We don't handle color translation just yet [we dont have to.. REMOVE REMOVE REMOVE]
237 OutputGDI->DIB_BitBlt(OutputObj, InputObj, OutputGDI, InputGDI, &OutputRect, &InputPoint, ColorTranslation);
239 IntEngLeave(&EnterLeaveDest);
240 IntEngLeave(&EnterLeaveSource);
246 // Clip the blt to the clip rectangle
247 EngIntersectRect(&rclTmp, &OutputRect, &ClipRegion->rclBounds);
249 ptlTmp.x = InputPoint.x + rclTmp.left - OutputRect.left;
250 ptlTmp.y = InputPoint.y + rclTmp.top - OutputRect.top;
252 IntEngLeave(&EnterLeaveDest);
253 IntEngLeave(&EnterLeaveSource);
259 CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
262 EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
266 RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
267 RECTL* prcl = &RectEnum.arcl[0];
270 EngIntersectRect(prcl, prcl, &OutputRect);
272 ptlTmp.x = InputPoint.x + prcl->left - OutputRect.left;
273 ptlTmp.y = InputPoint.y + prcl->top - OutputRect.top;
277 } while (prcl < prclEnd);
282 IntEngLeave(&EnterLeaveDest);
283 IntEngLeave(&EnterLeaveSource);
288 IntEngLeave(&EnterLeaveDest);
289 IntEngLeave(&EnterLeaveSource);
295 IntEngBitBlt(SURFOBJ *DestObj,
299 XLATEOBJ *ColorTranslation,
311 if (NULL != SourceObj)
313 SourceGDI = (PSURFGDI) AccessInternalObjectFromUserObject(SourceObj);
314 MouseSafetyOnDrawStart(SourceObj, SourceGDI, SourcePoint->x, SourcePoint->y,
315 (SourcePoint->x + abs(DestRect->right - DestRect->left)),
316 (SourcePoint->y + abs(DestRect->bottom - DestRect->top)));
321 DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj);
322 MouseSafetyOnDrawStart(DestObj, DestGDI, DestRect->left, DestRect->top,
323 DestRect->right, DestRect->bottom);
325 /* Call the driver's DrvBitBlt if available */
326 if (NULL != DestGDI->BitBlt) {
327 ret = DestGDI->BitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
328 DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, rop4);
332 ret = EngBitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
333 DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, rop4);
336 MouseSafetyOnDrawEnd(DestObj, DestGDI);
337 if (NULL != SourceObj)
339 MouseSafetyOnDrawEnd(SourceObj, SourceGDI);