* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: bitblt.c,v 1.67 2004/12/30 02:32:18 navaraf Exp $
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
static BOOLEAN STDCALL
BltMask(SURFOBJ* Dest,
SURFOBJ* Source,
- SURFOBJ* Mask,
+ SURFOBJ* Mask,
XLATEOBJ* ColorTranslation,
RECTL* DestRect,
POINTL* SourcePoint,
static BYTE maskbit[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
/* Pattern brushes */
PGDIBRUSHINST GdiBrush = NULL;
- HBITMAP PatternSurface = NULL;
SURFOBJ *PatternObj = NULL;
PBITMAPOBJ PatternBitmap;
ULONG PatternWidth = 0, PatternHeight = 0, PatternY = 0;
-
+
if (Mask == NULL)
{
return FALSE;
GDIBRUSHINST,
BrushObject);
- PatternSurface = GdiBrush->GdiBrushObject->hbmPattern;
PatternBitmap = BITMAPOBJ_LockBitmap(GdiBrush->GdiBrushObject->hbmPattern);
if(PatternBitmap != NULL)
{
{
lMask = tMask;
c8 = SourcePoint->x & 0x07;
-
+
if(PatternBitmap != NULL)
PatternY = (DestRect->top + j) % PatternHeight;
-
+
for (i = 0; i < dx; i++)
{
if (0 != (*lMask & maskbit[c8]))
}
if (PatternBitmap != NULL)
- BITMAPOBJ_UnlockBitmap(PatternSurface);
+ BITMAPOBJ_UnlockBitmap(PatternBitmap);
return TRUE;
}
static BOOLEAN STDCALL
BltPatCopy(SURFOBJ* Dest,
SURFOBJ* Source,
- SURFOBJ* Mask,
+ SURFOBJ* Mask,
XLATEOBJ* ColorTranslation,
RECTL* DestRect,
POINTL* SourcePoint,
{
// These functions are assigned if we're working with a DIB
// The assigned functions depend on the bitsPerPixel of the DIB
- LONG y;
- ULONG LineWidth;
- LineWidth = DestRect->right - DestRect->left;
- for (y = DestRect->top; y < DestRect->bottom; y++)
- {
- DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_HLine(
- Dest, DestRect->left, DestRect->right, y, Brush->iSolidColor);
- }
+ DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_ColorFill(Dest, DestRect, Brush->iSolidColor);
return TRUE;
}
BltInfo.DestRect = *OutputRect;
BltInfo.SourcePoint = *InputPoint;
- if (Rop4 == SRCCOPY)
+ if (ROP3_TO_ROP4(SRCCOPY) == Rop4)
return DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
BltInfo.XlatePatternToDest = NULL;
BltInfo.Rop4 = Rop4;
/* Pattern brush */
- if (ROP_USES_PATTERN(Rop4) && Brush->iSolidColor == 0xFFFFFFFF)
+ if (ROP4_USES_PATTERN(Rop4) && Brush->iSolidColor == 0xFFFFFFFF)
{
GdiBrush = CONTAINING_RECORD(Brush, GDIBRUSHINST, BrushObject);
if((bmPattern = BITMAPOBJ_LockBitmap(GdiBrush->GdiBrushObject->hbmPattern)))
/* Pattern brush */
if (bmPattern != NULL)
{
- BITMAPOBJ_UnlockBitmap(BltInfo.PatternSurface->hsurf);
+ BITMAPOBJ_UnlockBitmap(bmPattern);
}
return Result;
BOOL UsesPattern;
POINTL AdjustedBrushOrigin;
- UsesSource = ((Rop4 & 0xCC0000) >> 2) != (Rop4 & 0x330000);
- UsesPattern = ((Rop4 & 0xF00000) >> 4) != (Rop4 & 0x0F0000);
- if (ROP_NOOP == Rop4)
+ UsesSource = ROP4_USES_SOURCE(Rop4);
+ UsesPattern = ROP4_USES_PATTERN(Rop4);
+ if (R4_NOOP == Rop4)
{
/* Copy destination onto itself: nop */
return TRUE;
}
- if (NULL != SourcePoint)
+ if (UsesSource && NULL != SourcePoint)
{
InputRect.left = SourcePoint->x;
InputRect.right = SourcePoint->x + (DestRect->right - DestRect->left);
return FALSE;
}
- OutputRect.left = DestRect->left + Translate.x;
- OutputRect.right = DestRect->right + Translate.x;
- OutputRect.top = DestRect->top + Translate.y;
- OutputRect.bottom = DestRect->bottom + Translate.y;
-
+ OutputRect.left += Translate.x;
+ OutputRect.right += Translate.x;
+ OutputRect.top += Translate.y;
+ OutputRect.bottom += Translate.y;
+
if(BrushOrigin)
{
AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
clippingType = ClipRegion->iDComplexity;
}
- if (0xaacc == Rop4)
+ if (R4_MASK == Rop4)
{
BltRectFunc = BltMask;
}
- else if (PATCOPY == Rop4)
+ else if (ROP3_TO_ROP4(PATCOPY) == Rop4)
{
-#if 0
- BltRectFunc = BltPatCopy;
-#else
if (Brush->iSolidColor == 0xFFFFFFFF)
BltRectFunc = CallDibBitBlt;
else
BltRectFunc = BltPatCopy;
-#endif
}
else
{
ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
- EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect);
- Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
- Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
- Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
- &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin, Rop4);
+ if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+ {
+ Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
+ Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
+ Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
+ &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin, Rop4);
+ }
break;
case DC_COMPLEX:
Ret = TRUE;
ClipRect.right = RectEnum.arcl[i].right + Translate.x;
ClipRect.top = RectEnum.arcl[i].top + Translate.y;
ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
- EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect);
- Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
- Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
- Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
- &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin, Rop4) &&
- Ret;
+ if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+ {
+ Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
+ Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
+ Ret = (*BltRectFunc)(OutputObj, InputObj, Mask,
+ ColorTranslation, &CombinedRect, &Pt,
+ MaskOrigin, Brush, &AdjustedBrushOrigin,
+ Rop4) && Ret;
+ }
}
}
while(EnumMore);
InputClippedRect.top = DestRect->bottom;
InputClippedRect.bottom = DestRect->top;
}
- UsesSource = ((Rop4 & 0xCC0000) >> 2) != (Rop4 & 0x330000);
+ UsesSource = ROP4_USES_SOURCE(Rop4);
if (UsesSource)
{
if (NULL == SourcePoint || NULL == SourceSurf)
{
return TRUE;
}
- InputPoint.x += OutputRect.left - DestRect->left;
- InputPoint.y += OutputRect.top - DestRect->top;
+ InputPoint.x += OutputRect.left - InputClippedRect.left;
+ InputPoint.y += OutputRect.top - InputClippedRect.top;
}
else
{
)
{
// www.osr.com/ddk/graphics/gdifncs_0bs7.htm
-
+
POINTL InputPoint;
RECTL InputRect;
RECTL OutputRect;
InputPoint.x = InputRect.left + Translate.x;
InputPoint.y = InputRect.top + Translate.y;
-
+
OutputRect = *prclDest;
/* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
OutputRect.right = prclDest->right + Translate.x;
OutputRect.top = prclDest->top + Translate.y;
OutputRect.bottom = prclDest->bottom + Translate.y;
-
+
if (NULL != BrushOrigin)
{
AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
DPRINT("EngStretchBlt isn't capable of handling mask yet.\n");
IntEngLeave(&EnterLeaveDest);
IntEngLeave(&EnterLeaveSource);
-
- return FALSE;
+
+ return FALSE;
}
else
{
static BOOLEAN STDCALL
AlphaBltMask(SURFOBJ* Dest,
SURFOBJ* Source,
- SURFOBJ* Mask,
+ SURFOBJ* Mask,
XLATEOBJ* ColorTranslation,
XLATEOBJ* SrcColorTranslation,
RECTL* DestRect,
r = (int)GetRValue(BrushColor);
g = (int)GetGValue(BrushColor);
b = (int)GetBValue(BrushColor);
-
+
tMask = Mask->pvScan0 + (SourcePoint->y * Mask->lDelta) + SourcePoint->x;
for (j = 0; j < dy; j++)
- {
- lMask = tMask;
- for (i = 0; i < dx; i++)
- {
- if (*lMask > 0)
- {
- if(*lMask == 0xff)
- {
- DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
- Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
- }
- else
- {
- Background = DIB_GetSource(Dest, DestRect->left + i, DestRect->top + j, SrcColorTranslation);
-
- NewColor =
- RGB((*lMask * (r - GetRValue(Background)) >> 8) + GetRValue(Background),
- (*lMask * (g - GetGValue(Background)) >> 8) + GetGValue(Background),
- (*lMask * (b - GetBValue(Background)) >> 8) + GetBValue(Background));
-
- Background = XLATEOBJ_iXlate(ColorTranslation, NewColor);
- DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
- Dest, DestRect->left + i, DestRect->top + j, Background);
- }
- }
- lMask++;
- }
- tMask += Mask->lDelta;
- }
+ {
+ lMask = tMask;
+ for (i = 0; i < dx; i++)
+ {
+ if (*lMask > 0)
+ {
+ if (*lMask == 0xff)
+ {
+ DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
+ Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
+ }
+ else
+ {
+ Background = DIB_GetSource(Dest, DestRect->left + i, DestRect->top + j,
+ SrcColorTranslation);
+
+ NewColor =
+ RGB((*lMask * (r - GetRValue(Background)) >> 8) + GetRValue(Background),
+ (*lMask * (g - GetGValue(Background)) >> 8) + GetGValue(Background),
+ (*lMask * (b - GetBValue(Background)) >> 8) + GetBValue(Background));
+
+ Background = XLATEOBJ_iXlate(ColorTranslation, NewColor);
+ DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
+ Dest, DestRect->left + i, DestRect->top + j, Background);
+ }
+ }
+ lMask++;
+ }
+ tMask += Mask->lDelta;
+ }
return TRUE;
}
else
{
- return FALSE;
+ return FALSE;
}
}
InputRect.bottom = DestRect->bottom - DestRect->top;
}
- if (! IntEngEnter(&EnterLeaveSource, NULL, &InputRect, TRUE, &Translate, &InputObj))
+ if (! IntEngEnter(&EnterLeaveSource, DestObj, &InputRect, TRUE, &Translate, &InputObj))
{
return FALSE;
}
OutputRect.right = DestRect->right + Translate.x;
OutputRect.top = DestRect->top + Translate.y;
OutputRect.bottom = DestRect->bottom + Translate.y;
-
+
if(BrushOrigin)
{
AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
&OutputRect, &InputPoint, MaskOrigin, Brush, &AdjustedBrushOrigin);
else
Ret = BltMask(OutputObj, InputObj, Mask, DestColorTranslation,
- &OutputRect, &InputPoint, MaskOrigin, Brush, &AdjustedBrushOrigin, 0xAACC);
+ &OutputRect, &InputPoint, MaskOrigin, Brush, &AdjustedBrushOrigin,
+ R4_MASK);
break;
case DC_RECT:
// Clip the blt to the clip rectangle
ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
- EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect);
- Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
- Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
- if(Mask->iBitmapFormat == BMF_8BPP)
- Ret = AlphaBltMask(OutputObj, InputObj, Mask, DestColorTranslation, SourceColorTranslation,
- &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin);
- else
- Ret = BltMask(OutputObj, InputObj, Mask, DestColorTranslation,
- &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin, 0xAACC);
+ if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+ {
+ Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
+ Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
+ if(Mask->iBitmapFormat == BMF_8BPP)
+ {
+ Ret = AlphaBltMask(OutputObj, InputObj, Mask, DestColorTranslation, SourceColorTranslation,
+ &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin);
+ }
+ else
+ {
+ Ret = BltMask(OutputObj, InputObj, Mask, DestColorTranslation,
+ &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin, R4_MASK);
+ }
+ }
break;
case DC_COMPLEX:
Ret = TRUE;
ClipRect.right = RectEnum.arcl[i].right + Translate.x;
ClipRect.top = RectEnum.arcl[i].top + Translate.y;
ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
- EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect);
- Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
- Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
- if(Mask->iBitmapFormat == BMF_8BPP)
- Ret = AlphaBltMask(OutputObj, InputObj, Mask, DestColorTranslation, SourceColorTranslation,
- &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin) && Ret;
- else
- Ret = BltMask(OutputObj, InputObj, Mask, DestColorTranslation,
- &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin, 0xAACC) && Ret;
+ if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+ {
+ Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
+ Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
+ if(Mask->iBitmapFormat == BMF_8BPP)
+ {
+ Ret = AlphaBltMask(OutputObj, InputObj, Mask,
+ DestColorTranslation,
+ SourceColorTranslation,
+ &CombinedRect, &Pt, MaskOrigin, Brush,
+ &AdjustedBrushOrigin) && Ret;
+ }
+ else
+ {
+ Ret = BltMask(OutputObj, InputObj, Mask,
+ DestColorTranslation, &CombinedRect, &Pt,
+ MaskOrigin, Brush, &AdjustedBrushOrigin,
+ R4_MASK) && Ret;
+ }
+ }
}
}
while(EnumMore);
IntEngLeave(&EnterLeaveDest);
IntEngLeave(&EnterLeaveSource);
- /* Dummy BitBlt to let driver know that something has changed.
- 0x00AA0029 is the Rop for D (no-op) */
- /* FIXME: Remove the typecast! */
- IntEngBitBlt((BITMAPOBJ*)DestObj, NULL, (BITMAPOBJ*)Mask, ClipRegion, DestColorTranslation,
- DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, ROP_NOOP);
-
return Ret;
}
BOOL STDCALL
IntEngMaskBlt(SURFOBJ *DestObj,
- SURFOBJ *Mask,
- CLIPOBJ *ClipRegion,
- XLATEOBJ *DestColorTranslation,
- XLATEOBJ *SourceColorTranslation,
- RECTL *DestRect,
- POINTL *SourcePoint,
- POINTL *MaskOrigin,
- BRUSHOBJ *Brush,
- POINTL *BrushOrigin)
+ SURFOBJ *Mask,
+ CLIPOBJ *ClipRegion,
+ XLATEOBJ *DestColorTranslation,
+ XLATEOBJ *SourceColorTranslation,
+ RECTL *DestRect,
+ POINTL *SourcePoint,
+ POINTL *MaskOrigin,
+ BRUSHOBJ *Brush,
+ POINTL *BrushOrigin)
{
BOOLEAN ret;
RECTL OutputRect;
MouseSafetyOnDrawStart(DestObj, OutputRect.left, OutputRect.top,
OutputRect.right, OutputRect.bottom);
+ /* Dummy BitBlt to let driver know that it should flush its changes.
+ This should really be done using a call to DrvSynchronizeSurface,
+ but the VMware driver doesn't hook that call. */
+ /* FIXME: Remove the typecast! */
+ IntEngBitBlt((BITMAPOBJ*)DestObj, NULL, (BITMAPOBJ*)Mask, ClipRegion, DestColorTranslation,
+ DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, R4_NOOP);
+
ret = EngMaskBitBlt(DestObj, Mask, ClipRegion, DestColorTranslation, SourceColorTranslation,
&OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin);
+ /* Dummy BitBlt to let driver know that something has changed. */
+ /* FIXME: Remove the typecast! */
+ IntEngBitBlt((BITMAPOBJ*)DestObj, NULL, (BITMAPOBJ*)Mask, ClipRegion, DestColorTranslation,
+ DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, R4_NOOP);
+
MouseSafetyOnDrawEnd(DestObj);
return ret;