GDI: Fix usage of gdi_get_brush_pointer.

Currently we get color from brush according to the offset in the paint region.
According to MSDN https://msdn.microsoft.com/en-us/library/dd183396(v=vs.85).aspx, it should get color according to dest position instead of offset in paint region.
This commit is contained in:
zihao.jiang 2015-10-16 02:52:02 +08:00
parent 6d810a5d78
commit 83d58ccfe8
6 changed files with 55 additions and 45 deletions

View File

@ -224,6 +224,8 @@ struct _GDI_BRUSH
int style;
HGDI_BITMAP pattern;
GDI_COLOR color;
int nXOrg;
int nYOrg;
};
typedef struct _GDI_BRUSH GDI_BRUSH;
typedef GDI_BRUSH* HGDI_BRUSH;

View File

@ -487,7 +487,7 @@ static BOOL BitBlt_PSDPxax_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
srcp++;
dstp++;
@ -518,7 +518,7 @@ static BOOL BitBlt_SPna_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidt
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *srcp & ~(*patp);
srcp++;
dstp++;
@ -543,7 +543,7 @@ static BOOL BitBlt_DPa_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *dstp & *patp;
dstp++;
@ -568,7 +568,7 @@ static BOOL BitBlt_PDxn_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidt
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *dstp ^ ~(*patp);
dstp++;
}
@ -626,7 +626,7 @@ static BOOL BitBlt_MERGECOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *srcp & *patp;
srcp++;
dstp++;
@ -692,13 +692,10 @@ static BOOL BitBlt_PATCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW
}
else
{
/* align pattern to 8x8 grid to make sure transition
between different pattern blocks are smooth */
if (hdcDest->brush->style == GDI_BS_HATCHED)
{
xOffset = nXDest % 8;
yOffset = nYDest % 8 + 2; // +2 added after comparison to mstsc
xOffset = 0;
yOffset = 2; // +2 added after comparison to mstsc
}
else
{
@ -713,7 +710,7 @@ static BOOL BitBlt_PATCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, x+xOffset, y+yOffset);
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, nXDest + x + xOffset, nYDest + y + yOffset);
*dstp = *patp;
dstp++;
}
@ -759,7 +756,7 @@ static BOOL BitBlt_PATINVERT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *patp ^ *dstp;
dstp++;
}
@ -789,7 +786,7 @@ static BOOL BitBlt_PATPAINT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int n
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *dstp | (*patp | ~(*srcp));
srcp++;
dstp++;

View File

@ -526,7 +526,7 @@ static BOOL BitBlt_PSDPxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
srcp++;
dstp++;
@ -583,7 +583,7 @@ static BOOL BitBlt_SPDSxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *srcp ^ (*patp & (*dstp ^ *srcp));
srcp++;
dstp++;
@ -614,7 +614,7 @@ static BOOL BitBlt_SPna_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidt
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *srcp & ~(*patp);
srcp++;
@ -668,7 +668,7 @@ static BOOL BitBlt_DPa_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *dstp & *patp;
dstp++;
@ -693,7 +693,7 @@ static BOOL BitBlt_PDxn_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidt
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *dstp ^ ~(*patp);
dstp++;
@ -723,7 +723,7 @@ static BOOL BitBlt_MERGECOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *srcp & *patp;
srcp++;
@ -790,13 +790,10 @@ static BOOL BitBlt_PATCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW
}
else
{
/* align pattern to 8x8 grid to make sure transition
between different pattern blocks are smooth */
if (hdcDest->brush->style == GDI_BS_HATCHED)
{
xOffset = nXDest % 8;
yOffset = nYDest % 8 + 2; // +2 added after comparison to mstsc
xOffset = 0;
yOffset = 2; // +2 added after comparison to mstsc
}
else
{
@ -811,7 +808,7 @@ static BOOL BitBlt_PATCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, x+xOffset, y+yOffset);
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, nXDest + x + xOffset, nYDest + y + yOffset);
*dstp = *patp;
dstp++;
}
@ -857,7 +854,7 @@ static BOOL BitBlt_PATINVERT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *patp ^ *dstp;
dstp++;
}
@ -887,7 +884,7 @@ static BOOL BitBlt_PATPAINT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int n
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *dstp | (*patp | ~(*srcp));
srcp++;
dstp++;

View File

@ -396,7 +396,7 @@ static BOOL BitBlt_PSDPxax_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi
{
for (x = 0; x < nWidth; x++)
{
patp = (BYTE*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (BYTE*) gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
srcp++;
dstp++;
@ -427,7 +427,7 @@ static BOOL BitBlt_SPna_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth
{
for (x = 0; x < nWidth; x++)
{
patp = gdi_get_brush_pointer(hdcDest, x, y);
patp = gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *srcp & ~(*patp);
patp++;
@ -454,7 +454,7 @@ static BOOL BitBlt_DPa_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth,
{
for (x = 0; x < nWidth; x++)
{
patp = gdi_get_brush_pointer(hdcDest, x, y);
patp = gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *dstp & *patp;
dstp++;
@ -479,7 +479,7 @@ static BOOL BitBlt_PDxn_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth
{
for (x = 0; x < nWidth; x++)
{
patp = gdi_get_brush_pointer(hdcDest, x, y);
patp = gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *dstp ^ ~(*patp);
patp++;
@ -538,7 +538,7 @@ static BOOL BitBlt_MERGECOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int n
{
for (x = 0; x < nWidth; x++)
{
patp = gdi_get_brush_pointer(hdcDest, x, y);
patp = gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *srcp & *patp;
patp++;
@ -604,13 +604,10 @@ static BOOL BitBlt_PATCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi
}
else
{
/* align pattern to 8x8 grid to make sure transition
between different pattern blocks are smooth */
if (hdcDest->brush->style == GDI_BS_HATCHED)
{
xOffset = nXDest % 8;
yOffset = nYDest % 8 + 2; // +2 added after comparison to mstsc
xOffset = 0;
yOffset = 2; // +2 added after comparison to mstsc
}
else
{
@ -625,7 +622,7 @@ static BOOL BitBlt_PATCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi
{
for (x = 0; x < nWidth; x++)
{
patp = gdi_get_brush_pointer(hdcDest, x+xOffset, y+yOffset);
patp = gdi_get_brush_pointer(hdcDest, nXDest + x + xOffset, nYDest + y + yOffset);
*dstp = *patp;
patp++;
@ -671,7 +668,7 @@ static BOOL BitBlt_PATINVERT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int n
{
for (x = 0; x < nWidth; x++)
{
patp = gdi_get_brush_pointer(hdcDest, x, y);
patp = gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *patp ^ *dstp;
patp++;
@ -703,7 +700,7 @@ static BOOL BitBlt_PATPAINT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW
{
for (x = 0; x < nWidth; x++)
{
patp = gdi_get_brush_pointer(hdcDest, x, y);
patp = gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
*dstp = *dstp | (*patp | ~(*srcp));
patp++;

View File

@ -53,7 +53,7 @@ p_PatBlt PatBlt_[5] =
HGDI_BRUSH gdi_CreateSolidBrush(GDI_COLOR crColor)
{
HGDI_BRUSH hBrush = (HGDI_BRUSH) malloc(sizeof(GDI_BRUSH));
HGDI_BRUSH hBrush = (HGDI_BRUSH) calloc(1, sizeof(GDI_BRUSH));
if (!hBrush)
return NULL;
hBrush->objectType = GDIOBJECT_BRUSH;
@ -71,7 +71,7 @@ HGDI_BRUSH gdi_CreateSolidBrush(GDI_COLOR crColor)
HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp)
{
HGDI_BRUSH hBrush = (HGDI_BRUSH) malloc(sizeof(GDI_BRUSH));
HGDI_BRUSH hBrush = (HGDI_BRUSH) calloc(1, sizeof(GDI_BRUSH));
if (!hBrush)
return NULL;
hBrush->objectType = GDIOBJECT_BRUSH;
@ -82,7 +82,7 @@ HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp)
HGDI_BRUSH gdi_CreateHatchBrush(HGDI_BITMAP hbmp)
{
HGDI_BRUSH hBrush = (HGDI_BRUSH) malloc(sizeof(GDI_BRUSH));
HGDI_BRUSH hBrush = (HGDI_BRUSH) calloc(1, sizeof(GDI_BRUSH));
if (!hBrush)
return NULL;
hBrush->objectType = GDIOBJECT_BRUSH;

View File

@ -371,6 +371,13 @@ INLINE BYTE* gdi_get_bitmap_pointer(HGDI_DC hdcBmp, int x, int y)
}
}
/**
* Get current color in brush bitmap according to dest coordinates.\n
* @msdn{dd183396}
* @param x dest x-coordinate
* @param y dest y-coordinate
* @return color
*/
INLINE BYTE* gdi_get_brush_pointer(HGDI_DC hdcBrush, int x, int y)
{
BYTE * p;
@ -381,10 +388,14 @@ INLINE BYTE* gdi_get_brush_pointer(HGDI_DC hdcBrush, int x, int y)
{
HGDI_BITMAP hBmpBrush = hdcBrush->brush->pattern;
/* According to @msdn{dd183396}, the system always positions a brush bitmap
* at the brush origin and copy across the client area.
* Calculate the offset of the mapped pixel in the brush bitmap according to
* brush origin and dest coordinates */
if (x >= 0 && y >= 0)
{
x = x % hBmpBrush->width;
y = y % hBmpBrush->height;
x = (x + hBmpBrush->width - (hdcBrush->brush->nXOrg % hBmpBrush->width)) % hBmpBrush->width;
y = (y + hBmpBrush->height - (hdcBrush->brush->nYOrg % hBmpBrush->height)) % hBmpBrush->height;
p = hBmpBrush->data + (y * hBmpBrush->scanline) + (x * hBmpBrush->bytesPerPixel);
return p;
}
@ -661,6 +672,8 @@ static BOOL gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
ret = FALSE;
goto out_error;
}
gdi->drawing->hdc->brush->nXOrg = brush->x;
gdi->drawing->hdc->brush->nYOrg = brush->y;
if (!gdi_PatBlt(gdi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect,
patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop)))
@ -719,6 +732,8 @@ static BOOL gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
ret = FALSE;
goto out_error;
}
gdi->drawing->hdc->brush->nXOrg = brush->x;
gdi->drawing->hdc->brush->nYOrg = brush->y;
if (!gdi_PatBlt(gdi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect,
patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop)))
@ -952,6 +967,8 @@ static BOOL gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
gdi_DeleteObject((HGDIOBJECT) hBmp);
goto out_fail;
}
gdi->drawing->hdc->brush->nXOrg = brush->x;
gdi->drawing->hdc->brush->nYOrg = brush->y;
gdi_BitBlt(gdi->drawing->hdc, mem3blt->nLeftRect, mem3blt->nTopRect,
mem3blt->nWidth, mem3blt->nHeight, bitmap->hdc,