- Raster operations in user mode are on higher bytes, whereas they are on lower bytes for drivers. Try to clarify this situation.
  - Add sanity check about what was said previously.
  - Implement masking in EngBitBlt
  - Rewrite NtGdiMaskBlt accordingly
  - Realize the palette when selecting it into a device DC.
  - When applying raster operation, do so only on 24 bits, we don't support alpha channel in win32k
This fixes VLC pink icons, Timo's MaskBlt tests and probably a lot of other things.
[SHELL32]
  - Use correct (?) raster operations for drawing sjortcuts.
Also note that now NtGdiMaskBlt locks the device contexts : this should avoid some race conditions, such as icons drawn on top of windows and the like.
Win32k sucks less.
So does reactos.
Dedicated to Timo. Sleep well, mate.

svn path=/trunk/; revision=50941
This commit is contained in:
Jérôme Gardou 2011-03-01 01:03:58 +00:00
parent 56cfac043d
commit 1ea8829ec1
20 changed files with 421 additions and 457 deletions

View file

@ -180,8 +180,8 @@ static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
if (NULL == SelectObject(ShortcutDC, ShortcutIconInfo.hbmColor)) goto fail;
if (!MaskBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight,
ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
ShortcutDC, 0, 0, ShortcutIconInfo.hbmMask, 0, 0,
MAKEROP4(SRCCOPY, 0xAA0000)))
ShortcutDC, 0, 0, ShortcutIconInfo.hbmMask, 0, 0,
MAKEROP4(0xAA0000, SRCCOPY)))
{
goto fail;
}

View file

@ -87,11 +87,12 @@ DIB_FUNCTIONS DibFunctionsForBitmapFormat[] =
}
};
ULONG
DIB_DoRop(ULONG Rop, ULONG Dest, ULONG Source, ULONG Pattern)
{
ULONG ResultNibble;
ULONG Result;
ULONG Result = 0;
ULONG i;
static const ULONG ExpandDest[16] =
{
@ -151,31 +152,34 @@ static const ULONG ExpandDest[16] =
0xF0F0F0F0 /* 1111 */,
};
/* Optimized code for the various named rop codes. */
switch (Rop)
Rop &=0xFF;
switch(Rop)
{
case ROP3_TO_ROP4(BLACKNESS): return(0);
case ROP3_TO_ROP4(NOTSRCERASE): return(~(Dest | Source));
case ROP3_TO_ROP4(NOTSRCCOPY): return(~Source);
case ROP3_TO_ROP4(SRCERASE): return((~Dest) & Source);
case ROP3_TO_ROP4(DSTINVERT): return(~Dest);
case ROP3_TO_ROP4(PATINVERT): return(Dest ^ Pattern);
case ROP3_TO_ROP4(SRCINVERT): return(Dest ^ Source);
case ROP3_TO_ROP4(SRCAND): return(Dest & Source);
case ROP3_TO_ROP4(MERGEPAINT): return(Dest | (~Source));
case ROP3_TO_ROP4(SRCPAINT): return(Dest | Source);
case ROP3_TO_ROP4(MERGECOPY): return(Source & Pattern);
case ROP3_TO_ROP4(SRCCOPY): return(Source);
case ROP3_TO_ROP4(PATCOPY): return(Pattern);
case ROP3_TO_ROP4(PATPAINT): return(Dest | (~Source) | Pattern);
case ROP3_TO_ROP4(WHITENESS): return(0xFFFFFFFF);
/* Optimized code for the various named rop codes. */
case R3_OPINDEX_NOOP: return(Dest);
case R3_OPINDEX_BLACKNESS: return(0);
case R3_OPINDEX_NOTSRCERASE: return(~(Dest | Source));
case R3_OPINDEX_NOTSRCCOPY: return(~Source);
case R3_OPINDEX_SRCERASE: return((~Dest) & Source);
case R3_OPINDEX_DSTINVERT: return(~Dest);
case R3_OPINDEX_PATINVERT: return(Dest ^ Pattern);
case R3_OPINDEX_SRCINVERT: return(Dest ^ Source);
case R3_OPINDEX_SRCAND: return(Dest & Source);
case R3_OPINDEX_MERGEPAINT: return(Dest | (~Source));
case R3_OPINDEX_SRCPAINT: return(Dest | Source);
case R3_OPINDEX_MERGECOPY: return(Source & Pattern);
case R3_OPINDEX_SRCCOPY: return(Source);
case R3_OPINDEX_PATCOPY: return(Pattern);
case R3_OPINDEX_PATPAINT: return(Dest | (~Source) | Pattern);
case R3_OPINDEX_WHITENESS: return(0xFFFFFFFF);
}
/* Expand the ROP operation to all four bytes */
Rop &= 0xFF;
Rop |= (Rop << 24) | (Rop << 16) | (Rop << 8);
/* Do the operation on four bits simultaneously. */
Result = 0;
for (i = 0; i < 8; i++)
for (i = 0; i < 6; i++)
{
ResultNibble = Rop & ExpandDest[Dest & 0xF] & ExpandSource[Source & 0xF] & ExpandPattern[Pattern & 0xF];
Result |= (((ResultNibble & 0xFF000000) ? 0x8 : 0x0) | ((ResultNibble & 0x00FF0000) ? 0x4 : 0x0) |

View file

@ -31,7 +31,7 @@ typedef struct _BLTINFO
POINTL SourcePoint;
BRUSHOBJ *Brush;
POINTL BrushOrigin;
ULONG Rop4;
ROP4 Rop4;
} BLTINFO, *PBLTINFO;
typedef VOID (*PFN_DIB_PutPixel)(SURFOBJ*,LONG,LONG,ULONG);

View file

@ -380,7 +380,7 @@ DIB_1BPP_BitBlt(PBLTINFO BltInfo)
Pattern |= (DIB_GetSourceIndex(PatternObj, (X + BrushOrigin.x + k) % PatternWidth, PatternY) << (31 - k));
}
Dest = DIB_DoRop(Rop4, Dest, Source, Pattern);
Dest = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern);
Dest &= ~((1 << (31 - NoBits)) - 1);
Dest |= *((PBYTE)DestBits) & ((1 << (31 - NoBits)) - 1);

View file

@ -43,6 +43,8 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFOBJ *Ma
LONG PatternX = 0, PatternY = 0;
ASSERT(IS_VALID_ROP4(ROP));
BOOL UsesSource = ROP4_USES_SOURCE(ROP);
BOOL UsesPattern = ROP4_USES_PATTERN(ROP);
@ -122,7 +124,7 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFOBJ *Ma
{
sx = SourceRect->left+(DesX - DestRect->left) * SrcWidth / DstWidth;
if (sx < 0 || sy < 0 ||
MaskSurf->sizlBitmap.cx < sx || MaskSurf->sizlBitmap.cy < sy ||
MaskSurf->sizlBitmap.cx < sx || MaskSurf->sizlBitmap.cy < sy ||
fnMask_GetPixel(MaskSurf, sx, sy) != 0)
{
CanDraw = FALSE;
@ -137,10 +139,10 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFOBJ *Ma
{
Source = XLATEOBJ_iXlate(ColorTranslation, fnSource_GetPixel(SourceSurf, sx, sy));
}
else
else
{
Source = 0;
CanDraw = (ROP3_TO_ROP4(SRCCOPY) != ROP);
CanDraw = ((ROP & 0xFF) != R3_OPINDEX_SRCCOPY);
}
}

View file

@ -27,11 +27,11 @@ typedef BOOLEAN (APIENTRY *PBLTRECTFUNC)(SURFOBJ* OutputObj,
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,
@ -46,19 +46,21 @@ BltMask(SURFOBJ* psoDest,
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);
@ -80,6 +82,18 @@ BltMask(SURFOBJ* psoDest,
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;
@ -92,48 +106,64 @@ BltMask(SURFOBJ* psoDest,
{
PatternX0 += PatternWidth;
}
for (y = prclDest->top; y < prclDest->bottom; y++)
{
pjMskCurrent = pjMskLine;
fjMaskBit = fjMaskBit0;
PatternX = PatternX0;
for (x = prclDest->left; x < prclDest->right; x++)
{
if (*pjMskCurrent & fjMaskBit)
{
fnDest_PutPixel(psoDest, x, y,
fnPattern_GetPixel(psoPattern, PatternX, PatternY));
}
fjMaskBit = _rotr8(fjMaskBit, 1);
pjMskCurrent += (fjMaskBit >> 7);
PatternX++;
PatternX %= PatternWidth;
}
pjMskLine += psoMask->lDelta;
PatternY++;
PatternY %= PatternHeight;
}
PatternX = PatternX0;
}
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++)
for (y = prclDest->top; y < prclDest->bottom; y++)
{
pjMskCurrent = pjMskLine;
fjMaskBit = fjMaskBit0;
for (x = prclDest->left; x < prclDest->right; x++)
{
Rop4 = (*pjMskCurrent & fjMaskBit) ? fgndRop : bkgndRop;
if(psurfPattern)
{
if (*pjMskCurrent & fjMaskBit)
{
fnDest_PutPixel(psoDest, x, y, Pattern);
}
fjMaskBit = _rotr8(fjMaskBit, 1);
pjMskCurrent += (fjMaskBit >> 7);
if(ROP4_USES_PATTERN(Rop4))
Pattern = fnPattern_GetPixel(psoPattern, PatternX, PatternY);
PatternX++;
PatternX %= PatternWidth;
}
pjMskLine += psoMask->lDelta;
if(psoSource)
{
if(ROP4_USES_SOURCE(Rop4))
{
Source = XLATEOBJ_iXlate(ColorTranslation,
fnSrc_GetPixel(psoSource, SrcX, SrcY));
}
SrcX++;
}
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;
}
}
@ -153,7 +183,7 @@ BltPatCopy(SURFOBJ* Dest,
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
@ -188,7 +218,7 @@ CallDibBitBlt(SURFOBJ* OutputObj,
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;
@ -244,7 +274,7 @@ NtGdiEngBitBlt(
IN POINTL *pptlMask,
IN BRUSHOBJ *pbo,
IN POINTL *pptlBrush,
IN ROP4 rop4 )
IN ROP4 Rop4)
{
RECTL rclTrg;
POINTL ptlSrc;
@ -272,7 +302,7 @@ NtGdiEngBitBlt(
}
_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);
}
/*
@ -289,7 +319,7 @@ EngBitBlt(SURFOBJ *DestObj,
POINTL *MaskOrigin,
BRUSHOBJ *pbo,
POINTL *BrushOrigin,
ROP4 rop4)
ROP4 Rop4)
{
BYTE clippingType;
RECTL CombinedRect;
@ -306,16 +336,20 @@ EngBitBlt(SURFOBJ *DestObj,
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)
{
@ -434,11 +468,11 @@ EngBitBlt(SURFOBJ *DestObj,
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;
@ -456,7 +490,7 @@ EngBitBlt(SURFOBJ *DestObj,
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 */
@ -470,7 +504,7 @@ EngBitBlt(SURFOBJ *DestObj,
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:
@ -511,7 +545,7 @@ EngBitBlt(SURFOBJ *DestObj,
Ret = (*BltRectFunc)(OutputObj, InputObj, Mask,
ColorTranslation, &CombinedRect, &Pt,
MaskOrigin, pbo, &AdjustedBrushOrigin,
rop4) && Ret;
Rop4) && Ret;
}
}
}
@ -534,7 +568,7 @@ IntEngBitBlt(
POINTL *pptlMask,
BRUSHOBJ *pbo,
POINTL *pptlBrush,
ROP4 rop4)
ROP4 Rop4)
{
SURFACE *psurfTrg;
SURFACE *psurfSrc = NULL;
@ -550,6 +584,11 @@ IntEngBitBlt(
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 */
@ -564,7 +603,7 @@ IntEngBitBlt(
pco = NULL;
}
if (ROP4_USES_SOURCE(rop4))
if (ROP4_USES_SOURCE(Rop4))
{
ASSERT(psoSrc);
psurfSrc = CONTAINING_RECORD(psoSrc, SURFACE, SurfObj);
@ -614,7 +653,7 @@ IntEngBitBlt(
pptlMask,
pbo,
pptlBrush,
rop4);
Rop4);
// FIXME: cleanup temp surface!
@ -820,7 +859,7 @@ EngMaskBitBlt(SURFOBJ *psoDest,
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
@ -840,7 +879,7 @@ EngMaskBitBlt(SURFOBJ *psoDest,
else
{
Ret = BltMask(psoOutput, NULL, psoInput, DestColorTranslation,
&CombinedRect, NULL, &Pt, pbo, &AdjustedBrushOrigin, R4_MASK);
&CombinedRect, NULL, &Pt, pbo, &AdjustedBrushOrigin, ROP4_MASK);
}
}
break;
@ -889,7 +928,7 @@ EngMaskBitBlt(SURFOBJ *psoDest,
Ret = BltMask(psoOutput, NULL, psoInput,
DestColorTranslation, &CombinedRect, NULL,
&Pt, pbo, &AdjustedBrushOrigin,
R4_MASK) && Ret;
ROP4_MASK) && Ret;
}
}
}
@ -954,7 +993,7 @@ IntEngMaskBlt(SURFOBJ *psoDest,
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);
@ -962,7 +1001,7 @@ IntEngMaskBlt(SURFOBJ *psoDest,
/* 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;
}

View file

@ -92,7 +92,7 @@ EngCopyBits(SURFOBJ *psoDest,
// If CopyBits wasn't hooked, BitBlt must be
ret = IntEngBitBlt(psoDest, psoSource,
NULL, Clip, ColorTranslation, DestRect, SourcePoint,
NULL, NULL, NULL, ROP3_TO_ROP4(SRCCOPY));
NULL, NULL, NULL, ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY));
goto cleanup;
}
@ -111,7 +111,7 @@ EngCopyBits(SURFOBJ *psoDest,
BltInfo.SourceSurface = psoSource;
BltInfo.PatternSurface = NULL;
BltInfo.XlateSourceToDest = ColorTranslation;
BltInfo.Rop4 = SRCCOPY;
BltInfo.Rop4 = ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY);
switch (clippingType)
{

View file

@ -175,7 +175,7 @@ IntHideMousePointer(
&ptlSave,
NULL,
NULL,
ROP3_TO_ROP4(SRCCOPY));
ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY));
}
VOID
@ -228,7 +228,7 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
NULL,
NULL,
NULL,
ROP3_TO_ROP4(SRCCOPY));
ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY));
/* Blt the pointer on the screen. */
if (pgp->psurfColor)
@ -243,7 +243,7 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
NULL,
NULL,
NULL,
ROP3_TO_ROP4(SRCAND));
ROP4_FROM_INDEX(R3_OPINDEX_SRCAND));
IntEngBitBlt(psoDest,
&pgp->psurfColor->SurfObj,
@ -255,7 +255,7 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
NULL,
NULL,
NULL,
ROP3_TO_ROP4(SRCINVERT));
ROP4_FROM_INDEX(R3_OPINDEX_SRCINVERT));
}
else
{
@ -269,7 +269,7 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
NULL,
NULL,
NULL,
ROP3_TO_ROP4(SRCAND));
ROP4_FROM_INDEX(R3_OPINDEX_SRCAND));
rclPointer.top += pgp->Size.cy;
@ -283,7 +283,7 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
NULL,
NULL,
NULL,
ROP3_TO_ROP4(SRCINVERT));
ROP4_FROM_INDEX(R3_OPINDEX_SRCINVERT));
}
}
@ -337,7 +337,7 @@ EngSetPointerShape(
rectl.bottom = sizel.cy;
/* Calculate lDelta for our surfaces. */
lDelta = WIDTH_BYTES_ALIGN32(sizel.cx,
lDelta = WIDTH_BYTES_ALIGN32(sizel.cx,
BitsPerFormat(pso->iBitmapFormat));
/* Create a bitmap for saving the pixels under the cursor. */

View file

@ -104,7 +104,7 @@ EngStretchBltROP(
IN POINTL *MaskOrigin,
IN ULONG Mode,
IN BRUSHOBJ *pbo,
IN DWORD ROP4)
IN ROP4 Rop4)
{
RECTL InputRect;
RECTL OutputRect;
@ -116,7 +116,7 @@ EngStretchBltROP(
PSTRETCHRECTFUNC BltRectFunc;
BOOLEAN Ret = TRUE;
POINTL AdjustedBrushOrigin;
BOOL UsesSource = ROP4_USES_SOURCE(ROP4);
BOOL UsesSource = ROP4_USES_SOURCE(Rop4);
BYTE clippingType;
RECTL ClipRect;
@ -132,6 +132,13 @@ EngStretchBltROP(
LONG SrcHeight;
LONG SrcWidth;
if (Rop4 == ROP4_NOOP)
{
/* Copy destination onto itself: nop */
return TRUE;
}
/* Determine clipping type */
if (ClipRegion == (CLIPOBJ *) NULL)
{
@ -142,12 +149,6 @@ EngStretchBltROP(
clippingType = ClipRegion->iDComplexity;
}
if (ROP4 == R4_NOOP)
{
/* Copy destination onto itself: nop */
return TRUE;
}
OutputRect = *prclDest;
if (OutputRect.right < OutputRect.left)
{
@ -257,7 +258,7 @@ EngStretchBltROP(
case DC_TRIVIAL:
Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
ColorTranslation, &OutputRect, &InputRect, MaskOrigin,
pbo, &AdjustedBrushOrigin, ROP4);
pbo, &AdjustedBrushOrigin, Rop4);
break;
case DC_RECT:
// Clip the blt to the clip rectangle
@ -278,7 +279,7 @@ EngStretchBltROP(
MaskOrigin,
pbo,
&AdjustedBrushOrigin,
ROP4);
Rop4);
}
break;
case DC_COMPLEX:
@ -323,7 +324,7 @@ EngStretchBltROP(
MaskOrigin,
pbo,
&AdjustedBrushOrigin,
ROP4);
Rop4);
}
}
}
@ -371,7 +372,7 @@ EngStretchBlt(
MaskOrigin,
Mode,
NULL,
ROP3_TO_ROP4(SRCCOPY));
ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY));
}
BOOL APIENTRY
@ -385,7 +386,7 @@ IntEngStretchBlt(SURFOBJ *psoDest,
POINTL *pMaskOrigin,
BRUSHOBJ *pbo,
POINTL *BrushOrigin,
ROP4 ROP)
DWORD Rop4)
{
BOOLEAN ret;
COLORADJUSTMENT ca;
@ -395,7 +396,7 @@ IntEngStretchBlt(SURFOBJ *psoDest,
RECTL InputClippedRect;
RECTL InputRect;
RECTL OutputRect;
BOOL UsesSource = ROP4_USES_SOURCE(ROP);
BOOL UsesSource = ROP4_USES_SOURCE(Rop4);
LONG InputClWidth, InputClHeight, InputWidth, InputHeight;
ASSERT(psoDest);
@ -403,6 +404,9 @@ IntEngStretchBlt(SURFOBJ *psoDest,
ASSERT(psurfDest);
ASSERT(DestRect);
/* Sanity check */
ASSERT(IS_VALID_ROP4(Rop4));
InputClippedRect = *DestRect;
if (InputClippedRect.right < InputClippedRect.left)
{
@ -485,7 +489,7 @@ IntEngStretchBlt(SURFOBJ *psoDest,
&MaskOrigin,
COLORONCOLOR,
pbo,
ROP);
Rop4);
}
if (! ret)
@ -502,7 +506,7 @@ IntEngStretchBlt(SURFOBJ *psoDest,
&MaskOrigin,
COLORONCOLOR,
pbo,
ROP);
Rop4);
}
return ret;

View file

@ -27,7 +27,7 @@ typedef struct _COLORSPACE
typedef struct _COLORTRANSFORMOBJ
{
BASEOBJECT BaseObject;
HANDLE hColorTransform;
HANDLE hColorTransform;
} GDICLRXFORM, COLORTRANSFORMOBJ, *PCOLORTRANSFORMOBJ;
extern HCOLORSPACE hStockColorSpace;
@ -36,6 +36,6 @@ const PALETTEENTRY* FASTCALL COLOR_GetSystemPaletteTemplate (VOID);
COLORREF APIENTRY COLOR_LookupNearestColor (PALETTEENTRY* palPalEntry, INT size, COLORREF color);
INT APIENTRY COLOR_PaletteLookupExactIndex (PALETTEENTRY* palPalEntry, INT size, COLORREF col);
INT APIENTRY COLOR_PaletteLookupPixel(PALETTEENTRY *palPalEntry, INT size, XLATEOBJ *XlateObj, COLORREF col, BOOL skipReserved);
UINT FASTCALL IntGdiRealizePalette (HDC);
UINT FASTCALL IntGdiRealizePalette (PDC);
HCOLORSPACE FASTCALL IntGdiCreateColorSpace(PLOGCOLORSPACEEXW);
BOOL FASTCALL IntGdiDeleteColorSpace(HCOLORSPACE);

View file

@ -17,19 +17,40 @@ typedef struct tagSPAN
ULONG Width;
} SPAN, *PSPAN;
#define R3_OPINDEX_SRCCOPY 0xcc
#define R3_OPINDEX_NOOP 0xaa
#define R4_NOOP ((R3_OPINDEX_NOOP << 8) | R3_OPINDEX_NOOP)
#define R4_MASK ((R3_OPINDEX_NOOP << 8) | R3_OPINDEX_SRCCOPY)
#define R3_OPINDEX_NOOP 0xAA
#define R3_OPINDEX_BLACKNESS 0x00
#define R3_OPINDEX_NOTSRCERASE 0x11
#define R3_OPINDEX_NOTSRCCOPY 0x33
#define R3_OPINDEX_SRCERASE 0x44
#define R3_OPINDEX_DSTINVERT 0x55
#define R3_OPINDEX_PATINVERT 0x5A
#define R3_OPINDEX_SRCINVERT 0x66
#define R3_OPINDEX_SRCAND 0x88
#define R3_OPINDEX_MERGEPAINT 0xBB
#define R3_OPINDEX_MERGECOPY 0xC0
#define R3_OPINDEX_SRCCOPY 0xCC
#define R3_OPINDEX_SRCPAINT 0xEE
#define R3_OPINDEX_PATCOPY 0xF0
#define R3_OPINDEX_PATPAINT 0xFB
#define R3_OPINDEX_WHITENESS 0xFF
#define ROP2_TO_MIX(Rop2) (((Rop2) << 8) | (Rop2))
#define ROP3_USES_DEST(Rop3) ((((Rop3) & 0xAA0000) >> 1) != ((Rop3) & 0x550000))
#define ROP4_USES_DEST(Rop4) (((((Rop4) & 0xAA) >> 1) != ((Rop4) & 0x55)) || ((((Rop4) & 0xAA00) >> 1) != ((Rop4) & 0x5500)))
#define ROP3_USES_SOURCE(Rop3) ((((Rop3) & 0xCC0000) >> 2) != ((Rop3) & 0x330000))
#define ROP4_USES_SOURCE(Rop4) (((((Rop4) & 0xCC) >> 2) != ((Rop4) & 0x33)) || ((((Rop4) & 0xCC00) >> 2) != ((Rop4) & 0x3300)))
#define ROP3_USES_PATTERN(Rop3) ((((Rop3) & 0xF00000) >> 4) != ((Rop3) & 0x0F0000))
#define ROP4_FROM_INDEX(index) ((index) | ((index) << 8))
#define ROP4_USES_SOURCE(Rop4) (((((Rop4) & 0xCC00) >> 2) != ((Rop4) & 0x3300)) || ((((Rop4) & 0xCC) >> 2) != ((Rop4) & 0x33)))
#define ROP4_USES_MASK(Rop4) (((Rop4) & 0xFF00) != (((Rop4) & 0xff) << 8))
#define ROP4_USES_DEST(Rop4) (((((Rop4) & 0xAA) >> 1) != ((Rop4) & 0x55)) || ((((Rop4) & 0xAA00) >> 1) != ((Rop4) & 0x5500)))
#define ROP4_USES_PATTERN(Rop4) (((((Rop4) & 0xF0) >> 4) != ((Rop4) & 0x0F)) || ((((Rop4) & 0xF000) >> 4) != ((Rop4) & 0x0F00)))
#define ROP3_TO_ROP4(Rop3) ((((Rop3) >> 8) & 0xff00) | (((Rop3) >> 16) & 0x00ff))
#define IS_VALID_ROP4(rop) (((rop) & 0xFFFF0000) == 0)
#define ROP4_FGND(Rop4) ((Rop4) & 0x00FF)
#define ROP4_BKGND(Rop4) (((Rop4) & 0xFF00) >> 8)
#define ROP4_NOOP (R3_OPINDEX_NOOP | (R3_OPINDEX_NOOP << 8))
#define ROP4_MASK (R3_OPINDEX_SRCCOPY | (R3_OPINDEX_NOOP << 8))
/* Definitions of IntEngXxx functions */

View file

@ -307,7 +307,7 @@ co_IntPaintWindows(PWND Wnd, ULONG Flags, BOOL Recurse)
/*
* IntInvalidateWindows
*
* Internal function used by IntRedrawWindow, UserRedrawDesktop,
* Internal function used by IntRedrawWindow, UserRedrawDesktop,
* co_WinPosSetWindowPos, IntValidateParent, co_UserRedrawWindow.
*/
VOID FASTCALL
@ -759,7 +759,7 @@ IntPrintWindow(
xSrc = 0;
ySrc = 0;
}
// TODO: Setup Redirection for Print.
return FALSE;
@ -1951,7 +1951,11 @@ UserRealizePalette(HDC hdc)
HWND hWnd;
DWORD Ret;
Ret = IntGdiRealizePalette(hdc);
PDC pdc = DC_LockDc(hdc);
if(!pdc)
return 0;
Ret = IntGdiRealizePalette(pdc);
if (Ret) // There was a change.
{
hWnd = IntWindowFromDC(hdc);
@ -1960,6 +1964,7 @@ UserRealizePalette(HDC hdc)
UserSendNotifyMessage((HWND)HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)hWnd, 0);
}
}
DC_UnlockDc(pdc);
return Ret;
}
@ -2065,7 +2070,7 @@ NtUserPrintWindow(
HDC hdcBlt,
UINT nFlags)
{
PWND Window;
PWND Window;
BOOL Ret = FALSE;
UserEnterExclusive();
@ -2075,7 +2080,7 @@ NtUserPrintWindow(
Window = UserGetWindowObject(hwnd);
// TODO: Add Desktop and MessageBox check via FNID's.
if ( Window )
{
{
/* Validate flags and check it as a mask for 0 or 1. */
if ( (nFlags & PW_CLIENTONLY) == nFlags)
Ret = IntPrintWindow( Window, hdcBlt, nFlags);

View file

@ -23,7 +23,11 @@
#define NDEBUG
#include <debug.h>
#define ROP_USES_SOURCE(Rop) (((((Rop) & 0xCC0000) >> 2) != ((Rop) & 0x330000)) || ((((Rop) & 0xCC000000) >> 2) != ((Rop) & 0x33000000)))
#define ROP_USES_MASK(Rop) (((Rop) & 0xFF000000) != (((Rop) & 0xff0000) << 8))
#define FIXUP_ROP(Rop) if(((Rop) & 0xFF000000) == 0) Rop = MAKEROP4((Rop), (Rop))
#define ROP_TO_ROP4(Rop) ((Rop) >> 16)
BOOL APIENTRY
NtGdiAlphaBlend(
@ -169,144 +173,21 @@ NtGdiBitBlt(
IN DWORD crBackColor,
IN FLONG fl)
{
PDC DCDest;
PDC DCSrc = NULL;
HDC ahDC[2];
PGDIOBJ apObj[2];
PDC_ATTR pdcattr = NULL;
SURFACE *BitmapDest, *BitmapSrc = NULL;
RECTL DestRect, SourceRect;
POINTL SourcePoint;
BOOL Status = FALSE;
EXLATEOBJ exlo;
XLATEOBJ *XlateObj = NULL;
BOOL UsesSource = ROP3_USES_SOURCE(ROP);
DPRINT("Locking DCs\n");
ahDC[0] = hDCDest;
ahDC[1] = hDCSrc ;
GDIOBJ_LockMultipleObjs(2, ahDC, apObj);
DCDest = apObj[0];
DCSrc = apObj[1];
if (NULL == DCDest)
{
if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
DPRINT("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCDest);
return FALSE;
}
if (DCDest->dctype == DC_TYPE_INFO)
{
if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
if (UsesSource)
{
if (NULL == DCSrc)
{
GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc);
return FALSE;
}
if (DCSrc->dctype == DC_TYPE_INFO)
{
GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
}
else if(DCSrc)
{
DPRINT1("Getting a valid Source handle without using source!!!\n");
GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
DCSrc = NULL ;
}
pdcattr = DCDest->pdcattr;
DestRect.left = XDest;
DestRect.top = YDest;
DestRect.right = XDest+Width;
DestRect.bottom = YDest+Height;
IntLPtoDP(DCDest, (LPPOINT)&DestRect, 2);
DestRect.left += DCDest->ptlDCOrig.x;
DestRect.top += DCDest->ptlDCOrig.y;
DestRect.right += DCDest->ptlDCOrig.x;
DestRect.bottom += DCDest->ptlDCOrig.y;
SourcePoint.x = XSrc;
SourcePoint.y = YSrc;
if (UsesSource)
{
IntLPtoDP(DCSrc, (LPPOINT)&SourcePoint, 1);
SourcePoint.x += DCSrc->ptlDCOrig.x;
SourcePoint.y += DCSrc->ptlDCOrig.y;
/* Calculate Source Rect */
SourceRect.left = SourcePoint.x;
SourceRect.top = SourcePoint.y;
SourceRect.right = SourcePoint.x + DestRect.right - DestRect.left;
SourceRect.bottom = SourcePoint.y + DestRect.bottom - DestRect.top ;
}
/* Prepare blit */
DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
DC_vUpdateFillBrush(DCDest);
/* Determine surfaces to be used in the bitblt */
BitmapDest = DCDest->dclevel.pSurface;
if (!BitmapDest)
goto cleanup;
if (UsesSource)
{
{
BitmapSrc = DCSrc->dclevel.pSurface;
if (!BitmapSrc)
goto cleanup;
}
}
/* Create the XLATEOBJ. */
if (UsesSource)
{
EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
XlateObj = &exlo.xlo;
}
/* Perform the bitblt operation */
Status = IntEngBitBlt(&BitmapDest->SurfObj,
BitmapSrc ? &BitmapSrc->SurfObj : NULL,
NULL,
DCDest->rosdc.CombinedClip,
XlateObj,
&DestRect,
&SourcePoint,
NULL,
&DCDest->eboFill.BrushObject,
&DCDest->dclevel.pbrFill->ptOrigin,
ROP3_TO_ROP4(ROP));
if (UsesSource)
EXLATEOBJ_vCleanup(&exlo);
cleanup:
DC_vFinishBlit(DCDest, DCSrc);
if (UsesSource)
{
GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
}
GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
return Status;
/* Forward to NtGdiMaskBlt */
// TODO : what's fl for?
return NtGdiMaskBlt(hDCDest,
XDest,
YDest,
Width,
Height,
hDCSrc,
XSrc,
YSrc,
NULL,
0,
0,
ROP,
crBackColor);
}
BOOL APIENTRY
@ -414,86 +295,6 @@ done:
return Ret;
}
/***********************************************************************
* MaskBlt
* Ported from WINE by sedwards 11-4-03
*
* Someone thought it would be faster to do it here and then switch back
* to GDI32. I dunno. Write a test and let me know.
* A. It should be in here!
*/
static const DWORD ROP3Table[256] =
{
0x000042, 0x010289, 0x020C89, 0x0300AA, 0x040C88, 0x0500A9, 0x060865, 0x0702C5,
0x080F08, 0x090245, 0x0A0329, 0x0B0B2A, 0x0C0324, 0x0D0B25, 0x0E08A5, 0x0F0001,
0x100C85, 0x1100A6, 0x120868, 0x1302C8, 0x140869, 0x1502C9, 0x165CCA, 0x171D54,
0x180D59, 0x191CC8, 0x1A06C5, 0x1B0768, 0x1C06CA, 0x1D0766, 0x1E01A5, 0x1F0385,
0x200F09, 0x210248, 0x220326, 0x230B24, 0x240D55, 0x251CC5, 0x2606C8, 0x271868,
0x280369, 0x2916CA, 0x2A0CC9, 0x2B1D58, 0x2C0784, 0x2D060A, 0x2E064A, 0x2F0E2A,
0x30032A, 0x310B28, 0x320688, 0x330008, 0x3406C4, 0x351864, 0x3601A8, 0x370388,
0x38078A, 0x390604, 0x3A0644, 0x3B0E24, 0x3C004A, 0x3D18A4, 0x3E1B24, 0x3F00EA,
0x400F0A, 0x410249, 0x420D5D, 0x431CC4, 0x440328, 0x450B29, 0x4606C6, 0x47076A,
0x480368, 0x4916C5, 0x4A0789, 0x4B0605, 0x4C0CC8, 0x4D1954, 0x4E0645, 0x4F0E25,
0x500325, 0x510B26, 0x5206C9, 0x530764, 0x5408A9, 0x550009, 0x5601A9, 0x570389,
0x580785, 0x590609, 0x5A0049, 0x5B18A9, 0x5C0649, 0x5D0E29, 0x5E1B29, 0x5F00E9,
0x600365, 0x6116C6, 0x620786, 0x630608, 0x640788, 0x650606, 0x660046, 0x6718A8,
0x6858A6, 0x690145, 0x6A01E9, 0x6B178A, 0x6C01E8, 0x6D1785, 0x6E1E28, 0x6F0C65,
0x700CC5, 0x711D5C, 0x720648, 0x730E28, 0x740646, 0x750E26, 0x761B28, 0x7700E6,
0x7801E5, 0x791786, 0x7A1E29, 0x7B0C68, 0x7C1E24, 0x7D0C69, 0x7E0955, 0x7F03C9,
0x8003E9, 0x810975, 0x820C49, 0x831E04, 0x840C48, 0x851E05, 0x8617A6, 0x8701C5,
0x8800C6, 0x891B08, 0x8A0E06, 0x8B0666, 0x8C0E08, 0x8D0668, 0x8E1D7C, 0x8F0CE5,
0x900C45, 0x911E08, 0x9217A9, 0x9301C4, 0x9417AA, 0x9501C9, 0x960169, 0x97588A,
0x981888, 0x990066, 0x9A0709, 0x9B07A8, 0x9C0704, 0x9D07A6, 0x9E16E6, 0x9F0345,
0xA000C9, 0xA11B05, 0xA20E09, 0xA30669, 0xA41885, 0xA50065, 0xA60706, 0xA707A5,
0xA803A9, 0xA90189, 0xAA0029, 0xAB0889, 0xAC0744, 0xAD06E9, 0xAE0B06, 0xAF0229,
0xB00E05, 0xB10665, 0xB21974, 0xB30CE8, 0xB4070A, 0xB507A9, 0xB616E9, 0xB70348,
0xB8074A, 0xB906E6, 0xBA0B09, 0xBB0226, 0xBC1CE4, 0xBD0D7D, 0xBE0269, 0xBF08C9,
0xC000CA, 0xC11B04, 0xC21884, 0xC3006A, 0xC40E04, 0xC50664, 0xC60708, 0xC707AA,
0xC803A8, 0xC90184, 0xCA0749, 0xCB06E4, 0xCC0020, 0xCD0888, 0xCE0B08, 0xCF0224,
0xD00E0A, 0xD1066A, 0xD20705, 0xD307A4, 0xD41D78, 0xD50CE9, 0xD616EA, 0xD70349,
0xD80745, 0xD906E8, 0xDA1CE9, 0xDB0D75, 0xDC0B04, 0xDD0228, 0xDE0268, 0xDF08C8,
0xE003A5, 0xE10185, 0xE20746, 0xE306EA, 0xE40748, 0xE506E5, 0xE61CE8, 0xE70D79,
0xE81D74, 0xE95CE6, 0xEA02E9, 0xEB0849, 0xEC02E8, 0xED0848, 0xEE0086, 0xEF0A08,
0xF00021, 0xF10885, 0xF20B05, 0xF3022A, 0xF40B0A, 0xF50225, 0xF60265, 0xF708C5,
0xF802E5, 0xF90845, 0xFA0089, 0xFB0A09, 0xFC008A, 0xFD0A0A, 0xFE02A9, 0xFF0062,
};
static __inline BYTE
SwapROP3_SrcDst(BYTE bRop3)
{
return (bRop3 & 0x99) | ((bRop3 & 0x22) << 1) | ((bRop3 & 0x44) >> 1);
}
#define FRGND_ROP3(ROP4) ((ROP4) & 0x00FFFFFF)
#define BKGND_ROP3(ROP4) (ROP3Table[(SwapROP3_SrcDst((ROP4)>>24)) & 0xFF])
#define DSTCOPY 0x00AA0029
#define DSTERASE 0x00220326 /* dest = dest & (~src) : DSna */
/* NOTE: An alternative algorithm could use a pattern brush, created from
* the mask bitmap and then use raster operation 0xCA to combine the fore
* and background bitmaps. In this case erasing the bits beforehand would be
* unneccessary. On the other hand the Operation does not provide an optimized
* version in the DIB code, while SRCAND and SRCPAINT do.
* A fully correct implementation would call Eng/DrvBitBlt, but our
* EngBitBlt completely ignores the mask surface.
*
* Msk Fg Bk => x
* P S D DPSDxax
* ------------------------------------------
* 0 0 0 0 0000xax = 000ax = 00x = 0
* 0 0 1 1 1001xax = 101ax = 10x = 1
* 0 1 0 0 0010xax = 001ax = 00x = 0
* 0 1 1 1 1011xax = 100ax = 10x = 1
* 1 0 0 0 0100xax = 010ax = 00x = 0
* 1 0 1 0 1101xax = 111ax = 11x = 0
* 1 1 0 1 0110xax = 011ax = 01x = 1
* 1 1 1 1 1111xax = 110ax = 10x = 1
*
* Operation index = 11001010 = 0xCA = PSaDPnao = DPSDxax
* ^ no, this is not random letters, its reverse Polish notation
*/
BOOL APIENTRY
NtGdiMaskBlt(
HDC hdcDest,
@ -510,97 +311,188 @@ NtGdiMaskBlt(
DWORD dwRop,
IN DWORD crBackColor)
{
HBITMAP hbmFore, hbmBack;
HDC hdcMask, hdcFore, hdcBack;
PDC pdc;
HBRUSH hbr;
COLORREF crFore, crBack;
PDC DCDest;
PDC DCSrc = NULL;
HDC ahDC[2];
PGDIOBJ apObj[2];
PDC_ATTR pdcattr = NULL;
SURFACE *BitmapDest, *BitmapSrc = NULL, *psurfMask = NULL;
RECTL DestRect, SourceRect;
POINTL SourcePoint, MaskPoint;
BOOL Status = FALSE;
EXLATEOBJ exlo;
XLATEOBJ *XlateObj = NULL;
BOOL UsesSource = ROP_USES_SOURCE(dwRop);
BOOL UsesMask;
if (!hbmMask)
return NtGdiBitBlt(hdcDest,
nXDest,
nYDest,
nWidth,
nHeight,
hdcSrc,
nXSrc,
nYSrc,
FRGND_ROP3(dwRop),
crBackColor,
0);
FIXUP_ROP(dwRop);
/* Lock the dest DC */
pdc = DC_LockDc(hdcDest);
if (!pdc) return FALSE;
UsesMask = ROP_USES_MASK(dwRop);
/* Get brush and colors from dest dc */
hbr = pdc->pdcattr->hbrush;
crFore = pdc->pdcattr->crForegroundClr;
crBack = pdc->pdcattr->crBackgroundClr;
//DPRINT1("dwRop : 0x%08x\n", dwRop);
/* Unlock the DC */
DC_UnlockDc(pdc);
/* Take care of mask bitmap */
if(hbmMask)
{
psurfMask = SURFACE_LockSurface(hbmMask);
if(!psurfMask)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
}
/* 1. Create mask bitmap's dc */
hdcMask = NtGdiCreateCompatibleDC(hdcDest);
NtGdiSelectBitmap(hdcMask, hbmMask);
if(UsesMask)
{
if(!psurfMask)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if(gajBitsPerFormat[psurfMask->SurfObj.iBitmapFormat] != 1)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
SURFACE_UnlockSurface(psurfMask);
return FALSE;
}
}
else if(psurfMask)
{
DPRINT1("Getting Mask bitmap without needing it?\n");
SURFACE_UnlockSurface(psurfMask);
psurfMask = NULL;
}
MaskPoint.x = xMask;
MaskPoint.y = yMask;
/* 2. Create masked Background bitmap */
/* Take care of source and destination bitmap */
DPRINT("Locking DCs\n");
ahDC[0] = hdcDest;
ahDC[1] = hdcSrc ;
GDIOBJ_LockMultipleObjs(2, ahDC, apObj);
DCDest = apObj[0];
DCSrc = apObj[1];
/* 2.1 Create bitmap */
hdcBack = NtGdiCreateCompatibleDC(hdcDest);
hbmBack = NtGdiCreateCompatibleBitmap(hdcDest, nWidth, nHeight);
NtGdiSelectBitmap(hdcBack, hbmBack);
if (NULL == DCDest)
{
if(DCSrc) DC_UnlockDc(DCSrc);
DPRINT("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hdcDest);
return FALSE;
}
/* 2.2 Copy source bitmap */
NtGdiSelectBrush(hdcBack, hbr);
IntGdiSetBkColor(hdcBack, crBack);
IntGdiSetTextColor(hdcBack, crFore);
NtGdiBitBlt(hdcBack, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, SRCCOPY, 0, 0);
if (DCDest->dctype == DC_TYPE_INFO)
{
if(DCSrc) DC_UnlockDc(DCSrc);
DC_UnlockDc(DCDest);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
/* 2.3 Do the background rop */
NtGdiBitBlt(hdcBack, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, BKGND_ROP3(dwRop), 0, 0);
if (UsesSource)
{
if (NULL == DCSrc)
{
DC_UnlockDc(DCDest);
DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hdcSrc);
return FALSE;
}
if (DCSrc->dctype == DC_TYPE_INFO)
{
DC_UnlockDc(DCDest);
DC_UnlockDc(DCSrc);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
}
else if(DCSrc)
{
DPRINT("Getting a valid Source handle without using source!!!\n");
DC_UnlockDc(DCSrc);
DCSrc = NULL ;
}
/* 2.4 Erase the foreground pixels */
IntGdiSetBkColor(hdcBack, RGB(0xFF, 0xFF, 0xFF));
IntGdiSetTextColor(hdcBack, RGB(0, 0, 0));
NtGdiBitBlt(hdcBack, 0, 0, nWidth, nHeight, hdcMask, xMask, yMask, SRCAND, 0, 0);
pdcattr = DCDest->pdcattr;
/* 3. Create masked Foreground bitmap */
DestRect.left = nXDest;
DestRect.top = nYDest;
DestRect.right = nXDest + nWidth;
DestRect.bottom = nYDest + nHeight;
IntLPtoDP(DCDest, (LPPOINT)&DestRect, 2);
/* 3.1 Create bitmap */
hdcFore = NtGdiCreateCompatibleDC(hdcDest);
hbmFore = NtGdiCreateCompatibleBitmap(hdcDest, nWidth, nHeight);
NtGdiSelectBitmap(hdcFore, hbmFore);
DestRect.left += DCDest->ptlDCOrig.x;
DestRect.top += DCDest->ptlDCOrig.y;
DestRect.right += DCDest->ptlDCOrig.x;
DestRect.bottom += DCDest->ptlDCOrig.y;
/* 3.2 Copy the dest bitmap */
NtGdiSelectBrush(hdcFore, hbr);
IntGdiSetBkColor(hdcFore, crBack);
IntGdiSetTextColor(hdcFore, crFore);
NtGdiBitBlt(hdcFore, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY, 0, 0);
SourcePoint.x = nXSrc;
SourcePoint.y = nYSrc;
/* 2.3 Do the foreground rop */
NtGdiBitBlt(hdcFore, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop), 0,0);
if (UsesSource)
{
IntLPtoDP(DCSrc, (LPPOINT)&SourcePoint, 1);
/* 2.4 Erase the background pixels */
IntGdiSetBkColor(hdcFore, RGB(0, 0, 0));
IntGdiSetTextColor(hdcFore, RGB(0xFF, 0xFF, 0xFF));
NtGdiBitBlt(hdcFore, 0, 0, nWidth, nHeight, hdcMask, xMask, yMask, SRCAND, 0, 0);
SourcePoint.x += DCSrc->ptlDCOrig.x;
SourcePoint.y += DCSrc->ptlDCOrig.y;
/* Calculate Source Rect */
SourceRect.left = SourcePoint.x;
SourceRect.top = SourcePoint.y;
SourceRect.right = SourcePoint.x + DestRect.right - DestRect.left;
SourceRect.bottom = SourcePoint.y + DestRect.bottom - DestRect.top ;
}
/* 3. Combine the fore and background into the background bitmap */
NtGdiBitBlt(hdcBack, 0, 0, nWidth, nHeight, hdcFore, 0, 0, SRCPAINT, 0, 0);
/* Prepare blit */
DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
/* 4. Copy the result to hdcDest */
NtGdiBitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcBack, 0, 0, SRCCOPY, 0, 0);
if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
DC_vUpdateFillBrush(DCDest);
/* 5. delete all temp objects */
NtGdiDeleteObjectApp(hdcBack);
NtGdiDeleteObjectApp(hdcFore);
NtGdiDeleteObjectApp(hdcMask);
GreDeleteObject(hbmFore);
GreDeleteObject(hbmBack);
/* Determine surfaces to be used in the bitblt */
BitmapDest = DCDest->dclevel.pSurface;
if (!BitmapDest)
goto cleanup;
return TRUE;
if (UsesSource)
{
{
BitmapSrc = DCSrc->dclevel.pSurface;
if (!BitmapSrc)
goto cleanup;
}
}
/* Create the XLATEOBJ. */
if (UsesSource)
{
EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
XlateObj = &exlo.xlo;
}
/* Perform the bitblt operation */
Status = IntEngBitBlt(&BitmapDest->SurfObj,
BitmapSrc ? &BitmapSrc->SurfObj : NULL,
psurfMask ? &psurfMask->SurfObj : NULL,
DCDest->rosdc.CombinedClip,
XlateObj,
&DestRect,
&SourcePoint,
&MaskPoint,
&DCDest->eboFill.BrushObject,
&DCDest->dclevel.pbrFill->ptOrigin,
ROP_TO_ROP4(dwRop));
if (UsesSource)
EXLATEOBJ_vCleanup(&exlo);
cleanup:
DC_vFinishBlit(DCDest, DCSrc);
if (UsesSource)
{
DC_UnlockDc(DCSrc);
}
DC_UnlockDc(DCDest);
if(psurfMask) SURFACE_UnlockSurface(psurfMask);
return Status;
}
BOOL
@ -655,7 +547,9 @@ GreStretchBltMask(
EXLATEOBJ exlo;
XLATEOBJ *XlateObj = NULL;
POINTL BrushOrigin;
BOOL UsesSource = ROP3_USES_SOURCE(ROP);
BOOL UsesSource = ROP_USES_SOURCE(ROP);
FIXUP_ROP(ROP);
if (0 == WidthDest || 0 == HeightDest || 0 == WidthSrc || 0 == HeightSrc)
{
@ -803,7 +697,7 @@ GreStretchBltMask(
BitmapMask ? &MaskPoint : NULL,
&DCDest->eboFill.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(ROP));
ROP_TO_ROP4(ROP));
if (UsesSource)
{
EXLATEOBJ_vCleanup(&exlo);
@ -877,6 +771,8 @@ IntPatBlt(
ASSERT(pbrush);
FIXUP_ROP(dwRop);
if (pbrush->flAttrs & GDIBRUSH_IS_NULL)
{
return TRUE;
@ -934,7 +830,7 @@ IntPatBlt(
NULL,
&eboFill.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(dwRop));
ROP_TO_ROP4(dwRop));
DC_vFinishBlit(pdc, NULL);
@ -1007,7 +903,7 @@ NtGdiPatBlt(
PDC_ATTR pdcattr;
BOOL ret;
BOOL UsesSource = ROP3_USES_SOURCE(ROP);
BOOL UsesSource = ROP_USES_SOURCE(ROP);
if (UsesSource)
{
/* in this case we call on GdiMaskBlt */

View file

@ -179,6 +179,11 @@ GdiSelectPalette(
DIRTY_BACKGROUND | DIRTY_TEXT;
}
if(pdc->dctype == DCTYPE_MEMORY)
{
IntGdiRealizePalette(pdc);
}
PALETTE_ShareUnlockPalette(ppal);
DC_UnlockDc(pdc);

View file

@ -531,7 +531,7 @@ NtGdiSetDIBitsToDeviceInternal(
NULL,
NULL,
NULL,
ROP3_TO_ROP4(SRCCOPY));
ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY));
/* Cleanup EXLATEOBJ */
EXLATEOBJ_vCleanup(&exlo);

View file

@ -1249,7 +1249,7 @@ IntFillRect( DC *dc,
PBRUSH pbrush,
BOOL Pen)
{
DWORD ROP = PATCOPY;
DWORD ROP = ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY);
RECTL DestRect;
SURFACE *psurf;
POINTL BrushOrigin;
@ -1291,7 +1291,7 @@ IntFillRect( DC *dc,
BrushOrigin.y = pbrush->ptOrigin.y;
if (pdcattr->jROP2 == R2_XORPEN)
ROP = PATINVERT;
ROP = ROP4_FROM_INDEX(R3_OPINDEX_PATINVERT);
Ret = IntEngBitBlt(
&psurf->SurfObj,
@ -1304,7 +1304,7 @@ IntFillRect( DC *dc,
NULL,
Pen ? &dc->eboLine.BrushObject : &dc->eboFill.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(ROP));
ROP);
}
return (int)Ret;

View file

@ -604,7 +604,7 @@ IntRectangle(PDC dc,
NULL,
&dc->eboFill.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY));
}
}

View file

@ -3269,7 +3269,7 @@ GreExtTextOutW(
&SourcePoint,
&dc->eboBackground.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY));
fuOptions &= ~ETO_OPAQUE;
DC_vFinishBlit(dc, NULL);
}
@ -3514,7 +3514,7 @@ GreExtTextOutW(
&SourcePoint,
&dc->eboBackground.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY));
MouseSafetyOnDrawEnd(dc->ppdev);
BackgroundLeft = DestRect.right;

View file

@ -723,26 +723,18 @@ NtGdiGetNearestPaletteIndex(
UINT
FASTCALL
IntGdiRealizePalette(HDC hDC)
IntGdiRealizePalette(PDC pdc)
{
UINT i, realize = 0;
PDC pdc;
PALETTE *ppalSurf, *ppalDC;
pdc = DC_LockDc(hDC);
if(!pdc)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return 0;
}
ppalSurf = pdc->dclevel.pSurface->ppal;
ppalDC = pdc->dclevel.ppal;
if(!(ppalSurf->flFlags & PAL_INDEXED))
{
// FIXME : set error?
goto cleanup;
return 0;
}
ASSERT(ppalDC->flFlags & PAL_INDEXED);
@ -755,8 +747,6 @@ IntGdiRealizePalette(HDC hDC)
InterlockedExchange((LONG*)&ppalSurf->IndexedColors[i], *(LONG*)&ppalDC->IndexedColors[i]);
}
cleanup:
DC_UnlockDc(pdc);
return realize;
}
@ -810,11 +800,9 @@ IntAnimatePalette(HPALETTE hPal,
{
if (dc->dclevel.hpal == hPal)
{
DC_UnlockDc(dc);
IntGdiRealizePalette(hDC);
IntGdiRealizePalette(dc);
}
else
DC_UnlockDc(dc);
DC_UnlockDc(dc);
}
UserReleaseDC(Wnd,hDC, FALSE);
}

View file

@ -606,14 +606,14 @@ IntFillPolygon(
BRUSHOBJ *BrushObj,
CONST PPOINT Points,
int Count,
RECTL DestRect,
RECTL DestRect,
POINTL *BrushOrigin)
{
FILL_EDGE_LIST *list = 0;
FILL_EDGE *ActiveHead = 0;
FILL_EDGE *pLeft, *pRight;
int ScanLine;
//DPRINT("IntFillPolygon\n");
/* Create Edge List. */
@ -657,11 +657,11 @@ IntFillPolygon(
NULL,
BrushObj,
BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY));
}
pLeft = pRight->pNext;
pRight = pLeft ? pLeft->pNext : NULL;
}
}
}
/* Free Edge List. If any are left. */