5 #include "../vgavideo/vgavideo.h"
9 typedef BOOL (*PFN_VGABlt)(SURFOBJ*, SURFOBJ*, XLATEOBJ*, RECTL*, POINTL*);
10 typedef BOOL STDCALL (*PBLTRECTFUNC)(PSURFOBJ OutputObj,
13 PXLATEOBJ ColorTranslation,
21 static BOOL FASTCALL VGADDI_IntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2)
23 static const RECTL rclEmpty = { 0, 0, 0, 0 };
25 prcDst->left = max(prcSrc1->left, prcSrc2->left);
26 prcDst->right = min(prcSrc1->right, prcSrc2->right);
28 if (prcDst->left < prcDst->right)
30 prcDst->top = max(prcSrc1->top, prcSrc2->top);
31 prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
33 if (prcDst->top < prcDst->bottom) return(TRUE);
42 DIBtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
43 RECTL *DestRect, POINTL *SourcePoint)
47 dx = DestRect->right - DestRect->left;
48 dy = DestRect->bottom - DestRect->top;
50 if (NULL == ColorTranslation || 0 != (ColorTranslation->flXlate & XO_TRIVIAL))
52 DIB_BltToVGA(DestRect->left, DestRect->top, dx, dy,
53 Source->pvScan0 + SourcePoint->y * Source->lDelta + (SourcePoint->x >> 1),
58 /* Perform color translation */
59 DIB_BltToVGAWithXlate(DestRect->left, DestRect->top, dx, dy,
60 Source->pvScan0 + SourcePoint->y * Source->lDelta + (SourcePoint->x >> 1),
61 Source->lDelta, ColorTranslation);
66 VGAtoDIB(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
67 RECTL *DestRect, POINTL *SourcePoint)
69 LONG i, j, dx, dy, RGBulong;
70 BYTE *GDIpos, *initial, idxColor;
72 // Used by the temporary DFB
75 PSURFOBJ TargetBitmapSurf;
76 HBITMAP hTargetBitmap;
80 // FIXME: Optimize to retrieve entire bytes at a time (see /display/vgavideo/vgavideo.c:vgaGetByte)
82 GDIpos = Dest->pvBits /* + (DestRect->top * Dest->lDelta) + (DestRect->left >> 1) */ ;
83 dx = DestRect->right - DestRect->left;
84 dy = DestRect->bottom - DestRect->top;
86 if(ColorTranslation == NULL)
88 // Prepare a Dest Dev Target and copy from the DFB to the DIB
89 DestDevSurf.NextScan = Dest->lDelta;
90 DestDevSurf.StartBmp = Dest->pvScan0;
92 DIB_BltFromVGA(SourcePoint->x, SourcePoint->y, dx, dy, Dest->pvBits, Dest->lDelta);
96 for(j=SourcePoint->y; j<SourcePoint->y+dy; j++)
99 for(i=SourcePoint->x; i<SourcePoint->x+dx; i++)
101 *GDIpos = XLATEOBJ_iXlate(ColorTranslation, vgaGetPixel(i, j));
104 GDIpos = initial + Dest->lDelta;
110 DFBtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
111 RECTL *DestRect, POINTL *SourcePoint)
113 // Do DFBs need color translation??
117 VGAtoDFB(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
118 RECTL *DestRect, POINTL *SourcePoint)
120 // Do DFBs need color translation??
124 VGAtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
125 RECTL *DestRect, POINTL *SourcePoint)
127 LONG i, i2, j, dx, dy, alterx, altery;
128 //LARGE_INTEGER Start, End; // for performance measurement only
129 static char buf[640];
133 dx = DestRect->right - DestRect->left;
134 dy = DestRect->bottom - DestRect->top;
136 alterx = DestRect->left - SourcePoint->x;
137 altery = DestRect->top - SourcePoint->y;
139 //KeQueryTickCount ( &Start );
144 if (SourcePoint->y >= DestRect->top)
146 for(j=SourcePoint->y; j<SourcePoint->y+dy; j++)
148 LONG j2 = j + altery;
149 vgaReadScan ( i, j, dx, buf );
150 vgaWriteScan ( i2, j2, dx, buf );
155 for(j=(SourcePoint->y+dy-1); j>=SourcePoint->y; j--)
157 LONG j2 = j + altery;
158 vgaReadScan ( i, j, dx, buf );
159 vgaWriteScan ( i2, j2, dx, buf );
163 //KeQueryTickCount ( &End );
164 //DbgPrint ( "VgaBitBlt timing: %lu\n", (ULONG)(End.QuadPart-Start.QuadPart) );
170 VGADDI_BltBrush(PSURFOBJ Dest, PSURFOBJ Source, PSURFOBJ MaskSurf,
171 PXLATEOBJ ColorTranslation, PRECT DestRect,
172 PPOINTL SourcePoint, PPOINTL MaskPoint,
173 PBRUSHOBJ Brush, PPOINTL BrushPoint, ROP4 Rop4)
175 UCHAR SolidColor = 0;
182 ULONG RasterOp = VGA_NORMAL;
184 /* Punt brush blts to non-device surfaces. */
185 if (Dest->iType != STYPE_DEVICE)
190 /* Punt pattern fills. */
191 if ((Rop4 == PATCOPY || Rop4 == PATINVERT) &&
192 Brush->iSolidColor == 0xFFFFFFFF)
197 /* Get the brush colour. */
200 case PATCOPY: SolidColor = Brush->iSolidColor; break;
201 case PATINVERT: SolidColor = Brush->iSolidColor; RasterOp = VGA_XOR; break;
202 case WHITENESS: SolidColor = 0xF; break;
203 case BLACKNESS: SolidColor = 0x0; break;
204 case DSTINVERT: SolidColor = 0xF; RasterOp = VGA_XOR; break;
207 /* Select write mode 3. */
208 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);
209 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x03);
211 /* Setup set/reset register. */
212 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x00);
213 WRITE_PORT_UCHAR((PUCHAR)GRA_D, (UCHAR)SolidColor);
215 /* Enable writes to all pixels. */
216 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);
217 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xFF);
219 /* Set up data rotate. */
220 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);
221 WRITE_PORT_UCHAR((PUCHAR)GRA_D, RasterOp);
223 /* Fill any pixels on the left which don't fall into a full row of eight. */
224 if ((DestRect->left % 8) != 0)
226 /* Disable writes to pixels outside of the destination rectangle. */
227 Mask = (1 << (8 - (DestRect->left % 8))) - 1;
228 if ((DestRect->right - DestRect->left) < (8 - (DestRect->left % 8)))
230 Mask &= ~((1 << (8 - (DestRect->right % 8))) - 1);
233 /* Write the same color to each pixel. */
234 Video = (PUCHAR)vidmem + DestRect->top * 80 + (DestRect->left >> 3);
235 for (i = DestRect->top; i < DestRect->bottom; i++, Video+=80)
237 (VOID)READ_REGISTER_UCHAR(Video);
238 WRITE_REGISTER_UCHAR(Video, Mask);
241 /* Have we finished. */
242 if ((DestRect->right - DestRect->left) < (8 - (DestRect->left % 8)))
244 /* Restore write mode 2. */
245 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);
246 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
248 /* Set up data rotate. */
249 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);
250 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
256 /* Fill any whole rows of eight pixels. */
257 Left = (DestRect->left + 7) & ~0x7;
258 Length = (DestRect->right >> 3) - (Left >> 3);
259 for (i = DestRect->top; i < DestRect->bottom; i++)
261 Video = (PUCHAR)vidmem + i * 80 + (Left >> 3);
262 for (j = 0; j < Length; j++, Video++)
264 (VOID)READ_REGISTER_UCHAR(Video);
265 WRITE_REGISTER_UCHAR(Video, 0xFF);
269 /* Fill any pixels on the right which don't fall into a complete row. */
270 if ((DestRect->right % 8) != 0)
272 /* Disable writes to pixels outside the destination rectangle. */
273 Mask = ~((1 << (8 - (DestRect->right % 8))) - 1);
275 Video = (PUCHAR)vidmem + DestRect->top * 80 + (DestRect->right >> 3);
276 for (i = DestRect->top; i < DestRect->bottom; i++, Video+=80)
278 (VOID)READ_REGISTER_UCHAR(Video);
279 WRITE_REGISTER_UCHAR(Video, Mask);
283 /* Restore write mode 2. */
284 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);
285 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
287 /* Set up data rotate. */
288 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);
289 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
295 VGADDI_BltSrc(PSURFOBJ Dest, PSURFOBJ Source, PSURFOBJ Mask,
296 PXLATEOBJ ColorTranslation, PRECTL DestRect, PPOINTL SourcePoint,
297 PPOINTL MaskOrigin, PBRUSHOBJ Brush, PPOINTL BrushOrigin, ROP4 Rop4)
301 PFN_VGABlt BltOperation;
304 SourceType = Source->iType;
306 if (SourceType == STYPE_BITMAP && Dest->iType == STYPE_DEVICE)
308 BltOperation = DIBtoVGA;
310 else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_BITMAP)
312 BltOperation = VGAtoDIB;
314 else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_DEVICE)
316 BltOperation = VGAtoVGA;
318 else if (SourceType == STYPE_DEVBITMAP && Dest->iType == STYPE_DEVICE)
320 BltOperation = DFBtoVGA;
322 else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_DEVBITMAP)
324 BltOperation = VGAtoDFB;
328 /* Punt blts not involving a device or a device-bitmap. */
332 BltOperation(Dest, Source, ColorTranslation, DestRect, SourcePoint);
337 VGADDI_BltMask(PSURFOBJ Dest, PSURFOBJ Source, PSURFOBJ Mask,
338 PXLATEOBJ ColorTranslation, PRECTL DestRect,
339 PPOINTL SourcePoint, PPOINTL MaskPoint, BRUSHOBJ* Brush,
340 PPOINTL BrushPoint, ROP4 Rop4)
342 LONG i, j, dx, dy, idxColor, RGBulong = 0, c8;
343 BYTE *initial, *tMask, *lMask;
345 dx = DestRect->right - DestRect->left;
346 dy = DestRect->bottom - DestRect->top;
348 if (ColorTranslation == NULL)
352 tMask = Mask->pvBits;
359 if((*lMask & maskbit[c8]) != 0)
361 vgaPutPixel(DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
364 if(c8 == 8) { lMask++; c8=0; }
366 tMask += Mask->lDelta;
373 DrvBitBlt(SURFOBJ *Dest,
377 XLATEOBJ *ColorTranslation,
385 PBLTRECTFUNC BltRectFunc;
401 BltRectFunc = VGADDI_BltBrush;
405 if (BMF_4BPP == Source->iBitmapFormat && BMF_4BPP == Dest->iBitmapFormat)
407 BltRectFunc = VGADDI_BltSrc;
416 BltRectFunc = VGADDI_BltMask;
423 switch(NULL == Clip ? DC_TRIVIAL : Clip->iDComplexity)
426 Ret = (*BltRectFunc)(Dest, Source, Mask, ColorTranslation, DestRect,
427 SourcePoint, MaskPoint, Brush, BrushPoint,
431 // Clip the blt to the clip rectangle
432 VGADDI_IntersectRect(&CombinedRect, DestRect, &(Clip->rclBounds));
433 Pt.x = SourcePoint->x + CombinedRect.left - DestRect->left;
434 Pt.y = SourcePoint->y + CombinedRect.top - DestRect->top;
435 Ret = (*BltRectFunc)(Dest, Source, Mask, ColorTranslation, &CombinedRect,
436 &Pt, MaskPoint, Brush, BrushPoint,
443 if (DestRect->top <= SourcePoint->y)
445 Direction = DestRect->left < SourcePoint->x ? CD_RIGHTDOWN : CD_LEFTDOWN;
449 Direction = DestRect->left < SourcePoint->x ? CD_RIGHTUP : CD_LEFTUP;
456 CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, Direction, ENUM_RECT_LIMIT);
459 EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
461 for (i = 0; i < RectEnum.c; i++)
463 VGADDI_IntersectRect(&CombinedRect, DestRect, RectEnum.arcl + i);
464 Pt.x = SourcePoint->x + CombinedRect.left - DestRect->left;
465 Pt.y = SourcePoint->y + CombinedRect.top - DestRect->top;
466 Ret = (*BltRectFunc)(Dest, Source, Mask, ColorTranslation, &CombinedRect,
467 &Pt, MaskPoint, Brush, BrushPoint, rop4) &&