Fixed some warnings
[reactos.git] / reactos / subsys / win32k / eng / bitblt.c
1 /*
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
7 * REVISION HISTORY:
8 * 2/10/1999: Created
9 */
10
11 #include <ddk/winddi.h>
12 #include <ddk/ntddk.h>
13 #include <ntos/minmax.h>
14 #include "brush.h"
15 #include "enum.h"
16 #include "objects.h"
17
18 VOID BitBltCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
19 SURFGDI *DestGDI, SURFGDI *SourceGDI,
20 PRECTL DestRect, POINTL *SourcePoint,
21 ULONG Delta)
22 {
23 ULONG dy, leftOfSource, leftOfDest, Width, CopyPos;
24
25 // FIXME: Get ColorTranslation passed here and do something with it
26
27 leftOfSource = SourcePoint->x * SourceGDI->BytesPerPixel;
28 leftOfDest = DestRect->left * DestGDI->BytesPerPixel;
29 Width = (DestRect->right - DestRect->left) * DestGDI->BytesPerPixel;
30 CopyPos = leftOfDest;
31
32 for(dy=DestRect->top; dy<DestRect->bottom; dy++)
33 {
34 RtlCopyMemory(DestSurf->pvBits+CopyPos,
35 SourceSurf->pvBits+CopyPos,
36 Width);
37
38 CopyPos += Delta;
39 }
40 }
41
42 BOOL EngIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2)
43
44 {
45 static const RECTL rclEmpty = { 0, 0, 0, 0 };
46
47 prcDst->left = max(prcSrc1->left, prcSrc2->left);
48 prcDst->right = min(prcSrc1->right, prcSrc2->right);
49
50 if (prcDst->left < prcDst->right)
51 {
52 prcDst->top = max(prcSrc1->top, prcSrc2->top);
53 prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
54
55 if (prcDst->top < prcDst->bottom)
56 return(TRUE);
57 }
58
59 *prcDst = rclEmpty;
60
61 return(FALSE);
62 }
63
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)
69 {
70 BYTE clippingType;
71 RECTL rclTmp;
72 POINTL ptlTmp;
73 RECT_ENUM RectEnum;
74 BOOL EnumMore;
75 SURFGDI *DestGDI, *SourceGDI;
76 BOOLEAN canCopyBits;
77
78 // If we don't have to do anything special, we can punt to DrvCopyBits
79 // if it exists
80 if( (Mask == NULL) && (MaskRect == NULL) && (Brush == NULL) &&
81 (BrushOrigin == NULL) && (rop4 == 0) )
82 {
83 canCopyBits = TRUE;
84 } else
85 canCopyBits = FALSE;
86
87 // FIXME: Use XLATEOBJ to translate source bitmap into destination bitmap's
88 // format. Call DrvDitherColor function where necessary and if available
89
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
93 // DrvCopyBits
94
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
98
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))
101 {
102
103 // Destination surface is device managed
104 if(Dest->iType!=STYPE_BITMAP)
105 {
106 DestGDI = AccessInternalObjectFromUserObject(Dest);
107
108 if ((DestGDI->CopyBits!=NULL) && (canCopyBits == TRUE))
109 {
110 return DestGDI->CopyBits(Dest, Source, ClipRegion,
111 ColorTranslation, DestRect, SourcePoint);
112 }
113
114 if (DestGDI->BitBlt!=NULL)
115 {
116 return DestGDI->BitBlt(Dest, Source, Mask, ClipRegion,
117 ColorTranslation, DestRect, SourcePoint,
118 MaskRect, Brush, BrushOrigin, rop4);
119 }
120 }
121
122 // Source surface is device managed
123 if(Source->iType!=STYPE_BITMAP)
124 {
125 SourceGDI = AccessInternalObjectFromUserObject(Source);
126
127 if ((SourceGDI->CopyBits!=NULL) && (canCopyBits == TRUE))
128 {
129 return SourceGDI->CopyBits(Dest, Source, ClipRegion,
130 ColorTranslation, DestRect, SourcePoint);
131 }
132
133 if (SourceGDI->BitBlt!=NULL)
134 {
135 return SourceGDI->BitBlt(Dest, Source, Mask, ClipRegion,
136 ColorTranslation, DestRect, SourcePoint,
137 MaskRect, Brush, BrushOrigin, rop4);
138 }
139
140
141 // Should never get here, if it's not GDI managed then the device
142 // should take care of it
143
144 // FIXME: Error message here
145 }
146
147 }
148
149 DestGDI = AccessInternalObjectFromUserObject(Dest);
150 SourceGDI = AccessInternalObjectFromUserObject(Source);
151
152 // Determine clipping type
153 if (ClipRegion == (CLIPOBJ *) NULL)
154 {
155 clippingType = DC_TRIVIAL;
156 } else {
157 clippingType = ClipRegion->iDComplexity;
158 }
159
160 // We don't handle color translation just yet
161
162 if ((rop4 == 0x0000CCCC) &&
163 ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL)))
164 {
165 switch(clippingType)
166 {
167 case DC_TRIVIAL:
168 BitBltCopy(Dest, Source,
169 DestGDI, SourceGDI,
170 DestRect, SourcePoint, Source->lDelta);
171
172 return(TRUE);
173
174 case DC_RECT:
175
176 // Clip the blt to the clip rectangle
177
178 EngIntersectRect(&rclTmp, DestRect, &ClipRegion->rclBounds);
179
180 ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
181 ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
182
183 BitBltCopy(Dest, Source,
184 DestGDI, SourceGDI,
185 &rclTmp, &ptlTmp, Source->lDelta);
186
187 return(TRUE);
188
189 case DC_COMPLEX:
190
191 CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES,
192 CD_ANY, ENUM_RECT_LIMIT);
193
194 do {
195 EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum),
196 (PVOID) &RectEnum);
197
198 if (RectEnum.c > 0)
199 {
200 RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
201 RECTL* prcl = &RectEnum.arcl[0];
202
203 do {
204 EngIntersectRect(prcl, prcl, DestRect);
205
206 ptlTmp.x = SourcePoint->x + prcl->left
207 - DestRect->left;
208 ptlTmp.y = SourcePoint->y + prcl->top
209 - DestRect->top;
210
211 BitBltCopy(Dest, Source,
212 DestGDI, SourceGDI,
213 prcl, &ptlTmp, Source->lDelta);
214
215 prcl++;
216
217 } while (prcl < prclEnd);
218 }
219
220 } while(EnumMore);
221
222 return(TRUE);
223 }
224 }
225
226 return(FALSE);
227 }