static BOOLEAN APIENTRY
BltMask(SURFOBJ* psoDest,
- SURFOBJ* psoSource, // unused
+ SURFOBJ* psoSource,
SURFOBJ* psoMask,
- XLATEOBJ* ColorTranslation, // unused
+ XLATEOBJ* ColorTranslation,
RECTL* prclDest,
- POINTL* pptlSource, // unused
+ POINTL* pptlSource,
POINTL* pptlMask,
BRUSHOBJ* pbo,
POINTL* pptlBrush,
PSURFACE psurfPattern;
ULONG PatternWidth = 0, PatternHeight = 0;
LONG PatternX0 = 0, PatternX = 0, PatternY = 0;
+ LONG SrcX = 0, SrcY = 0;
PFN_DIB_PutPixel fnDest_PutPixel = NULL;
- PFN_DIB_GetPixel fnPattern_GetPixel = NULL;
- ULONG Pattern = 0;
+ PFN_DIB_GetPixel fnPattern_GetPixel = NULL, fnSrc_GetPixel = NULL, fnDest_GetPixel;
+ ULONG Pattern = 0, Source = 0, Dest = 0;
HBITMAP hbmPattern;
+ DWORD fgndRop, bkgndRop;
- ASSERT(psoSource == NULL);
- ASSERT(pptlSource == NULL);
+ ASSERT(IS_VALID_ROP4(Rop4));
- if (psoMask == NULL)
- {
- return FALSE;
- }
+ fgndRop = ROP4_FGND(Rop4);
+ bkgndRop = ROP4_BKGND(Rop4);
+ //DPRINT1("Rop4 : 0x%08x\n", Rop4);
+
+ /* Determine pattern */
if (pbo && pbo->iSolidColor == 0xFFFFFFFF)
{
pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
fjMaskBit0 = 0x80 >> (pptlMask->x & 0x07);
fnDest_PutPixel = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_PutPixel;
+ fnDest_GetPixel = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_GetPixel;
+
+ /* Do we have a source */
+ if(psoSource)
+ {
+ /* Sanity check */
+ ASSERT(ROP4_USES_SOURCE(Rop4));
+ fnSrc_GetPixel = DibFunctionsForBitmapFormat[psoSource->iBitmapFormat].DIB_GetPixel;
+ SrcY = pptlSource->y;
+ SrcX = pptlSource->x;
+ }
+
if (psurfPattern)
{
PatternY = (prclDest->top - pptlBrush->y) % PatternHeight;
{
PatternX0 += PatternWidth;
}
+ PatternX = PatternX0;
+ }
+ else
+ {
+ Pattern = pbo ? pbo->iSolidColor : 0;
+ }
- for (y = prclDest->top; y < prclDest->bottom; y++)
+ for (y = prclDest->top; y < prclDest->bottom; y++)
+ {
+ pjMskCurrent = pjMskLine;
+ fjMaskBit = fjMaskBit0;
+
+ for (x = prclDest->left; x < prclDest->right; x++)
{
- pjMskCurrent = pjMskLine;
- fjMaskBit = fjMaskBit0;
- PatternX = PatternX0;
+ Rop4 = (*pjMskCurrent & fjMaskBit) ? fgndRop : bkgndRop;
- for (x = prclDest->left; x < prclDest->right; x++)
+ if(psurfPattern)
{
- if (*pjMskCurrent & fjMaskBit)
- {
- fnDest_PutPixel(psoDest, x, y,
- fnPattern_GetPixel(psoPattern, PatternX, PatternY));
- }
- fjMaskBit = _rotr8(fjMaskBit, 1);
- pjMskCurrent += (fjMaskBit >> 7);
+ if(ROP4_USES_PATTERN(Rop4))
+ Pattern = fnPattern_GetPixel(psoPattern, PatternX, PatternY);
PatternX++;
PatternX %= PatternWidth;
}
- pjMskLine += psoMask->lDelta;
- PatternY++;
- PatternY %= PatternHeight;
- }
- }
- else
- {
- Pattern = pbo ? pbo->iSolidColor : 0;
- for (y = prclDest->top; y < prclDest->bottom; y++)
- {
- pjMskCurrent = pjMskLine;
- fjMaskBit = fjMaskBit0;
- for (x = prclDest->left; x < prclDest->right; x++)
+ if(psoSource)
{
- if (*pjMskCurrent & fjMaskBit)
+ if(ROP4_USES_SOURCE(Rop4))
{
- fnDest_PutPixel(psoDest, x, y, Pattern);
+ Source = XLATEOBJ_iXlate(ColorTranslation,
+ fnSrc_GetPixel(psoSource, SrcX, SrcY));
}
- fjMaskBit = _rotr8(fjMaskBit, 1);
- pjMskCurrent += (fjMaskBit >> 7);
+ SrcX++;
}
- pjMskLine += psoMask->lDelta;
+
+ if(ROP4_USES_DEST(Rop4))
+ Dest = fnDest_GetPixel(psoDest, x, y);
+
+ fnDest_PutPixel(psoDest,
+ x,
+ y,
+ DIB_DoRop(Rop4,
+ Dest,
+ Source,
+ Pattern));
+ fjMaskBit = _rotr8(fjMaskBit, 1);
+ pjMskCurrent += (fjMaskBit >> 7);
+ }
+ pjMskLine += psoMask->lDelta;
+ if(psurfPattern)
+ {
+ PatternY++;
+ PatternY %= PatternHeight;
+ PatternX = PatternX0;
+ }
+ if(psoSource)
+ {
+ SrcY++;
+ SrcX = pptlSource->x;
}
}
POINTL* MaskPoint,
BRUSHOBJ* pbo,
POINTL* BrushPoint,
- ROP4 Rop4)
+ DWORD Rop4)
{
// These functions are assigned if we're working with a DIB
// The assigned functions depend on the bitsPerPixel of the DIB
BltInfo.DestRect = *OutputRect;
BltInfo.SourcePoint = *InputPoint;
- if (ROP3_TO_ROP4(SRCCOPY) == Rop4)
+ if ((Rop4 & 0xFF) == R3_OPINDEX_SRCCOPY)
return DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
BltInfo.Brush = pbo;
IN POINTL *pptlMask,
IN BRUSHOBJ *pbo,
IN POINTL *pptlBrush,
- IN ROP4 rop4 )
+ IN ROP4 Rop4)
{
RECTL rclTrg;
POINTL ptlSrc;
}
_SEH2_END;
- return EngBitBlt(psoTrg, psoSrc, psoMask, pco, pxlo, &rclTrg, &ptlSrc, &ptlMask, pbo, &ptlBrush, rop4);
+ return EngBitBlt(psoTrg, psoSrc, psoMask, pco, pxlo, &rclTrg, &ptlSrc, &ptlMask, pbo, &ptlBrush, Rop4);
}
/*
POINTL *MaskOrigin,
BRUSHOBJ *pbo,
POINTL *BrushOrigin,
- ROP4 rop4)
+ ROP4 Rop4)
{
BYTE clippingType;
RECTL CombinedRect;
unsigned i;
POINTL Pt;
ULONG Direction;
- BOOL UsesSource;
+ BOOL UsesSource, UsesMask;
POINTL AdjustedBrushOrigin;
- UsesSource = ROP4_USES_SOURCE(rop4);
- if (R4_NOOP == rop4)
+ UsesSource = ROP4_USES_SOURCE(Rop4);
+ UsesMask = ROP4_USES_MASK(Rop4);
+
+ if (Rop4 == ROP4_NOOP)
{
/* Copy destination onto itself: nop */
return TRUE;
}
+ //DPRINT1("Rop4 : 0x%08x\n", Rop4);
+
OutputRect = *DestRect;
if (OutputRect.right < OutputRect.left)
{
clippingType = ClipRegion->iDComplexity;
}
- if (R4_MASK == rop4)
+ if (UsesMask)
{
BltRectFunc = BltMask;
}
- else if (ROP3_TO_ROP4(PATCOPY) == rop4)
+ else if ((Rop4 & 0xFF) == R3_OPINDEX_PATCOPY)
{
if (pbo && pbo->iSolidColor == 0xFFFFFFFF)
BltRectFunc = CallDibBitBlt;
case DC_TRIVIAL:
Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
&OutputRect, &InputPoint, MaskOrigin, pbo,
- &AdjustedBrushOrigin, rop4);
+ &AdjustedBrushOrigin, Rop4);
break;
case DC_RECT:
/* Clip the blt to the clip rectangle */
Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
&CombinedRect, &Pt, MaskOrigin, pbo,
- &AdjustedBrushOrigin, rop4);
+ &AdjustedBrushOrigin, Rop4);
}
break;
case DC_COMPLEX:
Ret = (*BltRectFunc)(OutputObj, InputObj, Mask,
ColorTranslation, &CombinedRect, &Pt,
MaskOrigin, pbo, &AdjustedBrushOrigin,
- rop4) && Ret;
+ Rop4) && Ret;
}
}
}
POINTL *pptlMask,
BRUSHOBJ *pbo,
POINTL *pptlBrush,
- ROP4 rop4)
+ ROP4 Rop4)
{
SURFACE *psurfTrg;
SURFACE *psurfSrc = NULL;
rclClipped = *prclTrg;
RECTL_vMakeWellOrdered(&rclClipped);
+ //DPRINT1("Rop4 : 0x%08x\n", Rop4);
+
+ /* Sanity check */
+ ASSERT(IS_VALID_ROP4(Rop4));
+
if (pco)
{
/* Clip target rect against the bounds of the clipping region */
pco = NULL;
}
- if (ROP4_USES_SOURCE(rop4))
+ if (ROP4_USES_SOURCE(Rop4))
{
ASSERT(psoSrc);
psurfSrc = CONTAINING_RECORD(psoSrc, SURFACE, SurfObj);
pptlMask,
pbo,
pptlBrush,
- rop4);
+ Rop4);
// FIXME: cleanup temp surface!
else
Ret = BltMask(psoOutput, NULL, psoInput, DestColorTranslation,
&OutputRect, NULL, &InputPoint, pbo, &AdjustedBrushOrigin,
- R4_MASK);
+ ROP4_MASK);
break;
case DC_RECT:
// Clip the blt to the clip rectangle
else
{
Ret = BltMask(psoOutput, NULL, psoInput, DestColorTranslation,
- &CombinedRect, NULL, &Pt, pbo, &AdjustedBrushOrigin, R4_MASK);
+ &CombinedRect, NULL, &Pt, pbo, &AdjustedBrushOrigin, ROP4_MASK);
}
}
break;
Ret = BltMask(psoOutput, NULL, psoInput,
DestColorTranslation, &CombinedRect, NULL,
&Pt, pbo, &AdjustedBrushOrigin,
- R4_MASK) && Ret;
+ ROP4_MASK) && Ret;
}
}
}
but the VMware driver doesn't hook that call. */
IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
DestRect, pptlMask, pptlMask, pbo, BrushOrigin,
- R4_NOOP);
+ ROP4_NOOP);
ret = EngMaskBitBlt(psoDest, psoMask, ClipRegion, DestColorTranslation, SourceColorTranslation,
&OutputRect, &InputPoint, pbo, BrushOrigin);
/* Dummy BitBlt to let driver know that something has changed. */
IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
DestRect, pptlMask, pptlMask, pbo, BrushOrigin,
- R4_NOOP);
+ ROP4_NOOP);
return ret;
}