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>
18 VOID
BitBltCopy(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
19 SURFGDI
*DestGDI
, SURFGDI
*SourceGDI
,
20 PRECTL DestRect
, POINTL
*SourcePoint
,
23 ULONG dy
, leftOfSource
, leftOfDest
, Width
, CopyPos
;
25 // FIXME: Get ColorTranslation passed here and do something with it
27 leftOfSource
= SourcePoint
->x
* SourceGDI
->BytesPerPixel
;
28 leftOfDest
= DestRect
->left
* DestGDI
->BytesPerPixel
;
29 Width
= (DestRect
->right
- DestRect
->left
) * DestGDI
->BytesPerPixel
;
32 for(dy
=DestRect
->top
; dy
<DestRect
->bottom
; dy
++)
34 RtlCopyMemory(DestSurf
->pvBits
+CopyPos
,
35 SourceSurf
->pvBits
+CopyPos
,
42 BOOL
EngIntersectRect(PRECTL prcDst
, PRECTL prcSrc1
, PRECTL prcSrc2
)
45 static const RECTL rclEmpty
= { 0, 0, 0, 0 };
47 prcDst
->left
= max(prcSrc1
->left
, prcSrc2
->left
);
48 prcDst
->right
= min(prcSrc1
->right
, prcSrc2
->right
);
50 if (prcDst
->left
< prcDst
->right
)
52 prcDst
->top
= max(prcSrc1
->top
, prcSrc2
->top
);
53 prcDst
->bottom
= min(prcSrc1
->bottom
, prcSrc2
->bottom
);
55 if (prcDst
->top
< prcDst
->bottom
)
64 BOOL
EngBitBlt(SURFOBJ
*Dest
, SURFOBJ
*Source
,
65 SURFOBJ
*Mask
, CLIPOBJ
*ClipRegion
,
66 XLATEOBJ
*ColorTranslation
, RECTL
*DestRect
,
67 POINTL
*SourcePoint
, POINTL
*MaskRect
,
68 BRUSHOBJ
*Brush
, POINTL
*BrushOrigin
, ROP4 rop4
)
75 SURFGDI
*DestGDI
, *SourceGDI
;
78 // If we don't have to do anything special, we can punt to DrvCopyBits
80 if( (Mask
== NULL
) && (MaskRect
== NULL
) && (Brush
== NULL
) &&
81 (BrushOrigin
== NULL
) && (rop4
== 0) )
87 // FIXME: Use XLATEOBJ to translate source bitmap into destination bitmap's
88 // format. Call DrvDitherColor function where necessary and if available
90 // FIXME: If canCopyBits == TRUE AND the driver has a DrvCopyBits then
91 // punt to EngCopyBits and not the driver's DrvCopyBits just yet so
92 // that the EngCopyBits can take care of the clipping drivers
95 // FIXME: Don't punt to DrvBitBlt straight away. Instead, mark a typedef'd
96 // function to go there instead of the Engine's bltting function
97 // so as to do the clipping for the driver
99 // Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap
100 if((Dest
->iType
!=STYPE_BITMAP
) || (Source
->iType
!=STYPE_BITMAP
))
103 // Destination surface is device managed
104 if(Dest
->iType
!=STYPE_BITMAP
)
106 DestGDI
= AccessInternalObjectFromUserObject(Dest
);
108 if ((DestGDI
->CopyBits
!=NULL
) && (canCopyBits
== TRUE
))
110 return DestGDI
->CopyBits(Dest
, Source
, ClipRegion
,
111 ColorTranslation
, DestRect
, SourcePoint
);
114 if (DestGDI
->BitBlt
!=NULL
)
116 return DestGDI
->BitBlt(Dest
, Source
, Mask
, ClipRegion
,
117 ColorTranslation
, DestRect
, SourcePoint
,
118 MaskRect
, Brush
, BrushOrigin
, rop4
);
122 // Source surface is device managed
123 if(Source
->iType
!=STYPE_BITMAP
)
125 SourceGDI
= AccessInternalObjectFromUserObject(Source
);
127 if ((SourceGDI
->CopyBits
!=NULL
) && (canCopyBits
== TRUE
))
129 return SourceGDI
->CopyBits(Dest
, Source
, ClipRegion
,
130 ColorTranslation
, DestRect
, SourcePoint
);
133 if (SourceGDI
->BitBlt
!=NULL
)
135 return SourceGDI
->BitBlt(Dest
, Source
, Mask
, ClipRegion
,
136 ColorTranslation
, DestRect
, SourcePoint
,
137 MaskRect
, Brush
, BrushOrigin
, rop4
);
141 // Should never get here, if it's not GDI managed then the device
142 // should take care of it
144 // FIXME: Error message here
149 DestGDI
= AccessInternalObjectFromUserObject(Dest
);
150 SourceGDI
= AccessInternalObjectFromUserObject(Source
);
152 // Determine clipping type
153 if (ClipRegion
== (CLIPOBJ
*) NULL
)
155 clippingType
= DC_TRIVIAL
;
157 clippingType
= ClipRegion
->iDComplexity
;
160 // We don't handle color translation just yet
162 if ((rop4
== 0x0000CCCC) &&
163 ((ColorTranslation
== NULL
) || (ColorTranslation
->flXlate
& XO_TRIVIAL
)))
168 BitBltCopy(Dest
, Source
,
170 DestRect
, SourcePoint
, Source
->lDelta
);
176 // Clip the blt to the clip rectangle
178 EngIntersectRect(&rclTmp
, DestRect
, &ClipRegion
->rclBounds
);
180 ptlTmp
.x
= SourcePoint
->x
+ rclTmp
.left
- DestRect
->left
;
181 ptlTmp
.y
= SourcePoint
->y
+ rclTmp
.top
- DestRect
->top
;
183 BitBltCopy(Dest
, Source
,
185 &rclTmp
, &ptlTmp
, Source
->lDelta
);
191 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
,
192 CD_ANY
, ENUM_RECT_LIMIT
);
195 EnumMore
= CLIPOBJ_bEnum(ClipRegion
,(ULONG
) sizeof(RectEnum
),
200 RECTL
* prclEnd
= &RectEnum
.arcl
[RectEnum
.c
];
201 RECTL
* prcl
= &RectEnum
.arcl
[0];
204 EngIntersectRect(prcl
, prcl
, DestRect
);
206 ptlTmp
.x
= SourcePoint
->x
+ prcl
->left
208 ptlTmp
.y
= SourcePoint
->y
+ prcl
->top
211 BitBltCopy(Dest
, Source
,
213 prcl
, &ptlTmp
, Source
->lDelta
);
217 } while (prcl
< prclEnd
);