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 <include/mouse.h>
18 #include <include/object.h>
19 #include <include/dib.h>
20 #include <include/surface.h>
21 #include <include/copybits.h>
23 BOOL EngIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2)
25 static const RECTL rclEmpty = { 0, 0, 0, 0 };
27 prcDst->left = max(prcSrc1->left, prcSrc2->left);
28 prcDst->right = min(prcSrc1->right, prcSrc2->right);
30 if (prcDst->left < prcDst->right)
32 prcDst->top = max(prcSrc1->top, prcSrc2->top);
33 prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
35 if (prcDst->top < prcDst->bottom) return(TRUE);
46 EngBitBlt(SURFOBJ *Dest,
50 XLATEOBJ *ColorTranslation,
64 PSURFGDI DestGDI, SourceGDI;
66 PSURFOBJ TempSurf = NULL;
72 if(Source != NULL) SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
73 if(Dest != NULL) DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
77 MouseSafetyOnDrawStart(Source, SourceGDI, SourcePoint->x, SourcePoint->y,
78 (SourcePoint->x + abs(DestRect->right - DestRect->left)),
79 (SourcePoint->y + abs(DestRect->bottom - DestRect->top)));
81 MouseSafetyOnDrawStart(Dest, DestGDI, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
83 // If we don't have to do anything special, we can punt to DrvCopyBits
85 if( (Mask == NULL) && (MaskRect == NULL) && (Brush == NULL) &&
86 (BrushOrigin == NULL) && (rop4 == 0) )
92 // Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap, IF:
93 // * The destination bitmap is not managed by the GDI OR
94 if(Dest->iType != STYPE_BITMAP)
96 // Destination surface is device managed
97 if (DestGDI->BitBlt!=NULL)
101 // Get the source into a format compatible surface
106 TempRect.bottom = DestRect->bottom - DestRect->top;
107 TempRect.right = DestRect->right - DestRect->left;
108 TempSize.cx = TempRect.right;
109 TempSize.cy = TempRect.bottom;
111 hTemp = EngCreateBitmap(TempSize,
112 DIB_GetDIBWidthBytes(DestRect->right - DestRect->left, BitsPerFormat(Dest->iBitmapFormat)),
113 Dest->iBitmapFormat, 0, NULL);
114 TempSurf = (PSURFOBJ)AccessUserObject((ULONG)hTemp);
116 // FIXME: Skip creating a TempSurf if we have the same BPP and palette
117 EngBitBlt(TempSurf, Source, NULL, NULL, ColorTranslation, &TempRect, SourcePoint, NULL, NULL, NULL, 0);
120 ret = DestGDI->BitBlt(Dest, TempSurf, Mask, ClipRegion,
121 NULL, DestRect, &TempPoint,
122 MaskRect, Brush, BrushOrigin, rop4);
124 MouseSafetyOnDrawEnd(Source, SourceGDI);
125 MouseSafetyOnDrawEnd(Dest, DestGDI);
131 /* The code currently assumes there will be a source bitmap. This is not true when, for example, using this function to
132 * paint a brush pattern on the destination. */
135 DbgPrint("EngBitBlt: A source is currently required, even though not all operations require one (FIXME)\n");
139 // * The source bitmap is not managed by the GDI and we didn't already obtain it using EngCopyBits from the device
140 if(Source->iType != STYPE_BITMAP && SourceGDI->CopyBits == NULL)
142 if (SourceGDI->BitBlt!=NULL)
144 // Request the device driver to return the bitmap in a format compatible with the device
145 ret = SourceGDI->BitBlt(Dest, Source, Mask, ClipRegion,
146 NULL, DestRect, SourcePoint,
147 MaskRect, Brush, BrushOrigin, rop4);
149 MouseSafetyOnDrawEnd(Source, SourceGDI);
150 MouseSafetyOnDrawEnd(Dest, DestGDI);
154 // Convert the surface from the driver into the required destination surface
158 // Determine clipping type
159 if (ClipRegion == (CLIPOBJ *) NULL)
161 clippingType = DC_TRIVIAL;
163 clippingType = ClipRegion->iDComplexity;
166 // We don't handle color translation just yet [we dont have to.. REMOVE REMOVE REMOVE]
170 CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation);
172 MouseSafetyOnDrawEnd(Source, SourceGDI);
173 MouseSafetyOnDrawEnd(Dest, DestGDI);
179 // Clip the blt to the clip rectangle
180 EngIntersectRect(&rclTmp, DestRect, &ClipRegion->rclBounds);
182 ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
183 ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
185 MouseSafetyOnDrawEnd(Source, SourceGDI);
186 MouseSafetyOnDrawEnd(Dest, DestGDI);
192 CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
195 EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
199 RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
200 RECTL* prcl = &RectEnum.arcl[0];
203 EngIntersectRect(prcl, prcl, DestRect);
205 ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left;
206 ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top;
210 } while (prcl < prclEnd);
215 MouseSafetyOnDrawEnd(Source, SourceGDI);
216 MouseSafetyOnDrawEnd(Dest, DestGDI);
221 MouseSafetyOnDrawEnd(Source, SourceGDI);
222 MouseSafetyOnDrawEnd(Dest, DestGDI);