cc89dc50196b714457c8ee3b33e5689bd128edbc
[reactos.git] / reactos / drivers / dd / vga / display / objects / bitblt.c
1 #include <ntddk.h>
2 #define NDEBUG
3 #include <debug.h>
4 #include "../vgaddi.h"
5 #include "../vgavideo/vgavideo.h"
6 #include "brush.h"
7 #include "bitblt.h"
8
9 // FIXME:
10 // RGBtoULONG (eng/xlate.c) will be faster than RtlCopyMemory?
11
12 // Note: All of our BitBlt ops expect to be working with 4BPP data
13
14 typedef BOOL (*PFN_VGABlt)(SURFOBJ *, SURFOBJ *, SURFOBJ *, XLATEOBJ *,
15 RECTL *, POINTL *, POINTL *,
16 BRUSHOBJ *, POINTL *, ROP4);
17
18 BOOL DIBtoVGA(
19 SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
20 RECTL *DestRect, POINTL *SourcePoint, POINTL *MaskPoint,
21 BRUSHOBJ *Brush, POINTL *BrushPoint, ROP4 rop4)
22 {
23 LONG i, j, dx, dy, alterx, altery, idxColor, RGBulong = 0, c8;
24 BYTE *GDIpos, *initial, *tMask, *lMask;
25
26 if(Source != NULL) {
27 GDIpos = Source->pvBits /* +
28 SourcePoint->y * Source->lDelta + (SourcePoint->x >> 1) */ ;
29 }
30
31 dx = DestRect->right - DestRect->left;
32 dy = DestRect->bottom - DestRect->top;
33
34 alterx = abs(SourcePoint->x - DestRect->left);
35 altery = abs(SourcePoint->y - DestRect->top);
36
37 // FIXME: ColorTranslation will never be null. We must always map the colors (see PCGPE's bmp.txt)
38
39 if(ColorTranslation == NULL)
40 {
41
42 if(Mask != NULL)
43 {
44 if(rop4 == 0xAACC) { // no source, just paint the brush according to the mask
45
46 tMask = Mask->pvBits;
47 for (j=0; j<dy; j++)
48 {
49 lMask = tMask;
50 c8 = 0;
51 for (i=0; i<dx; i++)
52 {
53 if((*lMask & maskbit[c8]) != 0)
54 vgaPutPixel(DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
55 c8++;
56 if(c8 == 8) { lMask++; c8=0; }
57 }
58 tMask += Mask->lDelta;
59 }
60
61 }
62 } else
63 DIB_BltToVGA(DestRect->left, DestRect->top, dx, dy, Source->pvBits, Source->lDelta);
64
65 } else {
66
67 // Perform color translation
68 for(j=SourcePoint->y; j<SourcePoint->y+dy; j++)
69 {
70 initial = GDIpos;
71
72 for(i=SourcePoint->x; i<SourcePoint->x+dx; i++)
73 {
74 idxColor = XLATEOBJ_iXlate(ColorTranslation, *GDIpos);
75 vgaPutPixel(i+alterx, j+altery, idxColor);
76 GDIpos+=1;
77 }
78 GDIpos = initial + Source->lDelta;
79 }
80 }
81 }
82
83 BOOL VGAtoDIB(
84 SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
85 RECTL *DestRect, POINTL *SourcePoint, POINTL *MaskPoint,
86 BRUSHOBJ *Brush, POINTL *BrushPoint, ROP4 rop4)
87 {
88 LONG i, j, dx, dy, RGBulong;
89 BYTE *GDIpos, *initial, idxColor;
90
91 // Used by the temporary DFB
92 PDEVSURF TargetSurf;
93 DEVSURF DestDevSurf;
94 PSURFOBJ TargetBitmapSurf;
95 HBITMAP hTargetBitmap;
96 SIZEL InterSize;
97 POINTL ZeroPoint;
98
99 // FIXME: Optimize to retrieve entire bytes at a time (see /display/vgavideo/vgavideo.c:vgaGetByte)
100
101 GDIpos = Dest->pvBits /* + (DestRect->top * Dest->lDelta) + (DestRect->left >> 1) */ ;
102 dx = DestRect->right - DestRect->left;
103 dy = DestRect->bottom - DestRect->top;
104
105 if(ColorTranslation == NULL)
106 {
107 // Prepare a Dest Dev Target and copy from the DFB to the DIB
108 DestDevSurf.NextScan = Dest->lDelta;
109 DestDevSurf.StartBmp = Dest->pvScan0;
110
111 DIB_BltFromVGA(SourcePoint->x, SourcePoint->y, dx, dy, Dest->pvBits, Dest->lDelta);
112
113 } else {
114 // Color translation
115 for(j=SourcePoint->y; j<SourcePoint->y+dy; j++)
116 {
117 initial = GDIpos;
118 for(i=SourcePoint->x; i<SourcePoint->x+dx; i++)
119 {
120 *GDIpos = XLATEOBJ_iXlate(ColorTranslation, vgaGetPixel(i, j));
121 GDIpos+=1;
122 }
123 GDIpos = initial + Dest->lDelta;
124 }
125 }
126 }
127
128 BOOL DFBtoVGA(
129 SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
130 RECTL *DestRect, POINTL *SourcePoint, POINTL *MaskPoint,
131 BRUSHOBJ *Brush, POINTL *BrushPoint, ROP4 rop4)
132 {
133 // Do DFBs need color translation??
134 }
135
136 BOOL VGAtoDFB(
137 SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
138 RECTL *DestRect, POINTL *SourcePoint, POINTL *MaskPoint,
139 BRUSHOBJ *Brush, POINTL *BrushPoint, ROP4 rop4)
140 {
141 // Do DFBs need color translation??
142 }
143
144 BOOL VGAtoVGA(
145 SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
146 RECTL *DestRect, POINTL *SourcePoint, POINTL *MaskPoint,
147 BRUSHOBJ *Brush, POINTL *BrushPoint, ROP4 rop4)
148 {
149 // FIXME: Use fast blts instead of get and putpixels
150
151 int i, j, dx, dy, alterx, altery, BltDirection;
152
153 // Calculate deltas
154
155 dx = DestRect->right - DestRect->left;
156 dy = DestRect->bottom - DestRect->top;
157
158 alterx = abs(SourcePoint->x - DestRect->left);
159 altery = abs(SourcePoint->y - DestRect->top);
160
161 // Determine bltting direction
162 // FIXME: should we perhaps make this an EngXxx function? Determining
163 // direction is probably used whenever the surfaces are the same (not
164 // just VGA screen)
165 if (SourcePoint->y >= DestRect->top)
166 {
167 if (SourcePoint->x >= DestRect->left)
168 {
169 BltDirection = CD_RIGHTDOWN;
170 }
171 else
172 {
173 BltDirection = CD_LEFTDOWN;
174 }
175 }
176 else
177 {
178 if (SourcePoint->x >= DestRect->left)
179 {
180 BltDirection = CD_RIGHTUP;
181 }
182 else
183 {
184 BltDirection = CD_LEFTUP;
185 }
186 }
187
188 // Do the VGA to VGA BitBlt
189 // FIXME: Right now we're only doing CN_LEFTDOWN and we're using slow
190 // get and put pixel routines
191
192 for(j=SourcePoint->y; j<SourcePoint->y+dy; j++)
193 {
194 for(i=SourcePoint->x; i<SourcePoint->x+dx; i++)
195 {
196 vgaPutPixel(i+alterx, j+altery, vgaGetPixel(i, j));
197 }
198 }
199
200 return TRUE;
201 }
202
203
204 BOOL STDCALL
205 DrvBitBlt(SURFOBJ *Dest,
206 SURFOBJ *Source,
207 SURFOBJ *Mask,
208 CLIPOBJ *Clip,
209 XLATEOBJ *ColorTranslation,
210 RECTL *DestRect,
211 POINTL *SourcePoint,
212 POINTL *MaskPoint,
213 BRUSHOBJ *Brush,
214 POINTL *BrushPoint,
215 ROP4 rop4)
216 {
217 RECT_ENUM RectEnum;
218 BOOL EnumMore;
219 PFN_VGABlt BltOperation;
220 ULONG SourceType;
221
222 if(Source == NULL)
223 {
224 SourceType = STYPE_BITMAP;
225 } else
226 SourceType = Source->iType;
227
228 DPRINT("VGADDIBitBlt: Dest->pvScan0: %08x\n", Dest->pvScan0);
229
230 // Determine the bltbit operation
231
232 if((SourceType == STYPE_BITMAP) && (Dest->iType == STYPE_DEVICE))
233 {
234 DPRINT("DIB2VGA\n");
235 BltOperation = DIBtoVGA;
236 } else
237 if((SourceType == STYPE_DEVICE) && (Dest->iType == STYPE_BITMAP))
238 {
239 DPRINT("VGA2DIB\n");
240 BltOperation = VGAtoDIB;
241 } else
242 if((SourceType == STYPE_DEVICE) && (Dest->iType == STYPE_DEVICE))
243 {
244 DPRINT("VGA2VGA\n");
245 BltOperation = VGAtoVGA;
246 } else
247 if((SourceType == STYPE_DEVBITMAP) && (Dest->iType == STYPE_DEVICE))
248 {
249 DPRINT("DFB2VGA\n");
250 BltOperation = DFBtoVGA;
251 } else
252 if((SourceType == STYPE_DEVICE) && (Dest->iType == STYPE_DEVBITMAP))
253 {
254 DPRINT("VGA2DFB\n");
255 BltOperation = VGAtoDFB;
256 } else
257 {
258 DPRINT("VGA:bitblt.c: Can't handle requested BitBlt operation (source:%u dest:%u)\n", SourceType, Dest->iType);
259 // Cannot handle given surfaces for VGA BitBlt
260 return FALSE;
261 }
262
263 // Perform the necessary operatings according to the clipping
264
265 if(Clip == NULL)
266 {
267 BltOperation(Dest, Source, Mask, ColorTranslation, DestRect,
268 SourcePoint, MaskPoint, Brush, BrushPoint, rop4);
269 } else
270 {
271 switch(Clip->iMode) {
272
273 case TC_RECTANGLES:
274
275 if (Clip->iDComplexity == DC_RECT)
276 {
277 // FIXME: Intersect clip rectangle
278
279 BltOperation(Dest, Source, Mask, ColorTranslation,
280 DestRect, SourcePoint, MaskPoint, Brush, BrushPoint, rop4);
281 } else {
282
283 // Enumerate all the rectangles and draw them
284
285 /* CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY,
286 ENUM_RECT_LIMIT);
287
288 do {
289 EnumMore = CLIPOBJ_bEnum(Clip, sizeof(RectEnum), (PVOID) &RectEnum);
290 // FIXME: Calc new source point (diff between new & old destrects?)
291
292 VGADDIFillSolid(Dest, Srouce, Mask,
293 &RectEnum.arcl[0], NewSourcePoint);
294
295 } while (EnumMore); */
296 }
297 }
298 }
299
300 return TRUE;
301 }