d3f4528223e37e6916ec451df05299b6263742f5
[reactos.git] / reactos / subsys / win32k / eng / copybits.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI EngCopyBits Function
5 * FILE: subsys/win32k/eng/copybits.c
6 * PROGRAMER: Jason Filby
7 * REVISION HISTORY:
8 * 8/18/1999: Created
9 */
10
11 #include <ddk/winddi.h>
12 #include "objects.h"
13 #include "clip.h"
14 #include "../dib/dib.h"
15 #include <include/mouse.h>
16 #include <include/object.h>
17 #include <include/eng.h>
18
19 BOOLEAN CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
20 SURFGDI *DestGDI, SURFGDI *SourceGDI,
21 PRECTL DestRect, POINTL *SourcePoint,
22 LONG Delta, XLATEOBJ *ColorTranslation)
23 {
24 LONG DestWidth, DestHeight, CurrentDestLine, CurrentSourceLine, CurrentDestCol, CurrentSourceCol, i, TranslationPixel;
25
26 PFN_DIB_GetPixel Source_DIB_GetPixel;
27 PFN_DIB_PutPixel Dest_DIB_PutPixel;
28
29 DestWidth = DestRect->right - DestRect->left;
30 DestHeight = DestRect->bottom - DestRect->top;
31 CurrentSourceCol = SourcePoint->x;
32 CurrentSourceLine = SourcePoint->y;
33
34 // Assign GetPixel DIB function according to bytes per pixel
35 switch(DestGDI->BitsPerPixel)
36 {
37 case 1:
38 return DIB_To_1BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
39 DestRect, SourcePoint, Delta, ColorTranslation);
40 break;
41
42 case 4:
43 return DIB_To_4BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
44 DestRect, SourcePoint, Delta, ColorTranslation);
45 break;
46
47 case 24:
48 return DIB_To_24BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
49 DestRect, SourcePoint, Delta, ColorTranslation);
50 break;
51
52 default:
53 return FALSE;
54 }
55
56 return TRUE;
57 }
58
59 BOOL STDCALL
60 EngCopyBits(SURFOBJ *Dest,
61 SURFOBJ *Source,
62 CLIPOBJ *Clip,
63 XLATEOBJ *ColorTranslation,
64 RECTL *DestRect,
65 POINTL *SourcePoint)
66 {
67 BOOLEAN ret;
68 SURFGDI *DestGDI, *SourceGDI;
69 BYTE clippingType;
70 RECTL rclTmp;
71 POINTL ptlTmp;
72 RECT_ENUM RectEnum;
73 BOOL EnumMore;
74
75 MouseSafetyOnDrawStart(Source, SourceGDI, SourcePoint->x, SourcePoint->y,
76 (SourcePoint->x + abs(DestRect->right - DestRect->left)),
77 (SourcePoint->y + abs(DestRect->bottom - DestRect->top)));
78 MouseSafetyOnDrawStart(Dest, DestGDI, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
79
80 // FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
81 // mark the copy block function to be DrvCopyBits instead of the
82 // GDI's copy bit function so as to remove clipping from the
83 // driver's responsibility
84
85 // If one of the surfaces isn't managed by the GDI
86 if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
87 {
88 // Destination surface is device managed
89 if(Dest->iType!=STYPE_BITMAP)
90 {
91 DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
92
93 if (DestGDI->CopyBits!=NULL)
94 {
95 ret = DestGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
96
97 MouseSafetyOnDrawEnd(Source, SourceGDI);
98 MouseSafetyOnDrawEnd(Dest, DestGDI);
99
100 return ret;
101 }
102 }
103
104 // Source surface is device managed
105 if(Source->iType!=STYPE_BITMAP)
106 {
107 SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
108
109 if (SourceGDI->CopyBits!=NULL)
110 {
111 ret = SourceGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
112
113 MouseSafetyOnDrawEnd(Source, SourceGDI);
114 MouseSafetyOnDrawEnd(Dest, DestGDI);
115
116 return ret;
117 }
118 }
119
120 // If CopyBits wasn't hooked, BitBlt must be
121 ret = EngBitBlt(Dest, Source,
122 NULL, Clip, ColorTranslation, DestRect, SourcePoint,
123 NULL, NULL, NULL, 0);
124
125 MouseSafetyOnDrawEnd(Source, SourceGDI);
126 MouseSafetyOnDrawEnd(Dest, DestGDI);
127
128 return ret;
129 }
130
131 // Determine clipping type
132 if (Clip == (CLIPOBJ *) NULL)
133 {
134 clippingType = DC_TRIVIAL;
135 } else {
136 clippingType = Clip->iDComplexity;
137 }
138
139 // We only handle XO_TABLE translations at the momement
140 if ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL) ||
141 (ColorTranslation->flXlate & XO_TABLE))
142 {
143 SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
144 DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
145
146 switch(clippingType)
147 {
148 case DC_TRIVIAL:
149 CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation);
150
151 MouseSafetyOnDrawEnd(Source, SourceGDI);
152 MouseSafetyOnDrawEnd(Dest, DestGDI);
153
154 return(TRUE);
155
156 case DC_RECT:
157 // Clip the blt to the clip rectangle
158 EngIntersectRect(&rclTmp, DestRect, &Clip->rclBounds);
159
160 ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
161 ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
162
163 CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, &rclTmp, &ptlTmp, Source->lDelta, ColorTranslation);
164
165 MouseSafetyOnDrawEnd(Source, SourceGDI);
166 MouseSafetyOnDrawEnd(Dest, DestGDI);
167
168 return(TRUE);
169
170 case DC_COMPLEX:
171
172 CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
173
174 do {
175 EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
176
177 if (RectEnum.c > 0)
178 {
179 RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
180 RECTL* prcl = &RectEnum.arcl[0];
181
182 do {
183 EngIntersectRect(prcl, prcl, DestRect);
184
185 ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left;
186 ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top;
187
188 if(!CopyBitsCopy(Dest, Source, DestGDI, SourceGDI,
189 prcl, &ptlTmp, Source->lDelta, ColorTranslation)) return FALSE;
190
191 prcl++;
192
193 } while (prcl < prclEnd);
194 }
195
196 } while(EnumMore);
197
198 MouseSafetyOnDrawEnd(Source, SourceGDI);
199 MouseSafetyOnDrawEnd(Dest, DestGDI);
200
201 return(TRUE);
202 }
203 }
204
205 MouseSafetyOnDrawEnd(Source, SourceGDI);
206 MouseSafetyOnDrawEnd(Dest, DestGDI);
207
208 return FALSE;
209 }