Merge pull request #2932 from realjiangms/fix_gdi_brush

GDI: Fix usage of gdi_get_brush_pointer.
This commit is contained in:
Hardening 2015-12-18 10:50:51 +01:00
commit df81e842a5
6 changed files with 55 additions and 45 deletions

View File

@ -225,6 +225,8 @@ struct _GDI_BRUSH
int style; int style;
HGDI_BITMAP pattern; HGDI_BITMAP pattern;
GDI_COLOR color; GDI_COLOR color;
int nXOrg;
int nYOrg;
}; };
typedef struct _GDI_BRUSH GDI_BRUSH; typedef struct _GDI_BRUSH GDI_BRUSH;
typedef GDI_BRUSH* HGDI_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++) 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); *dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
srcp++; srcp++;
dstp++; 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++) 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); *dstp = *srcp & ~(*patp);
srcp++; srcp++;
dstp++; 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++) 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 = *dstp & *patp;
dstp++; 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++) 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 = *dstp ^ ~(*patp);
dstp++; dstp++;
} }
@ -626,7 +626,7 @@ static BOOL BitBlt_MERGECOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int
{ {
for (x = 0; x < nWidth; x++) 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; *dstp = *srcp & *patp;
srcp++; srcp++;
dstp++; dstp++;
@ -692,13 +692,10 @@ static BOOL BitBlt_PATCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW
} }
else else
{ {
/* align pattern to 8x8 grid to make sure transition
between different pattern blocks are smooth */
if (hdcDest->brush->style == GDI_BS_HATCHED) if (hdcDest->brush->style == GDI_BS_HATCHED)
{ {
xOffset = nXDest % 8; xOffset = 0;
yOffset = nYDest % 8 + 2; // +2 added after comparison to mstsc yOffset = 2; // +2 added after comparison to mstsc
} }
else 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++) 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 = *patp;
dstp++; dstp++;
} }
@ -759,7 +756,7 @@ static BOOL BitBlt_PATINVERT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int
{ {
for (x = 0; x < nWidth; x++) 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 = *patp ^ *dstp;
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++) 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)); *dstp = *dstp | (*patp | ~(*srcp));
srcp++; srcp++;
dstp++; 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++) 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); *dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
srcp++; srcp++;
dstp++; 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++) 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)); *dstp = *srcp ^ (*patp & (*dstp ^ *srcp));
srcp++; srcp++;
dstp++; 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++) 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 & ~(*patp);
srcp++; 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++) 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 = *dstp & *patp;
dstp++; 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++) 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 = *dstp ^ ~(*patp);
dstp++; dstp++;
@ -723,7 +723,7 @@ static BOOL BitBlt_MERGECOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int
{ {
for (x = 0; x < nWidth; x++) 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 & *patp;
srcp++; srcp++;
@ -790,13 +790,10 @@ static BOOL BitBlt_PATCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW
} }
else else
{ {
/* align pattern to 8x8 grid to make sure transition
between different pattern blocks are smooth */
if (hdcDest->brush->style == GDI_BS_HATCHED) if (hdcDest->brush->style == GDI_BS_HATCHED)
{ {
xOffset = nXDest % 8; xOffset = 0;
yOffset = nYDest % 8 + 2; // +2 added after comparison to mstsc yOffset = 2; // +2 added after comparison to mstsc
} }
else 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++) 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 = *patp;
dstp++; dstp++;
} }
@ -857,7 +854,7 @@ static BOOL BitBlt_PATINVERT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int
{ {
for (x = 0; x < nWidth; x++) 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 = *patp ^ *dstp;
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++) 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)); *dstp = *dstp | (*patp | ~(*srcp));
srcp++; srcp++;
dstp++; 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++) 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); *dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
srcp++; srcp++;
dstp++; 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++) 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); *dstp = *srcp & ~(*patp);
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++) 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 = *dstp & *patp;
dstp++; 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++) 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 = *dstp ^ ~(*patp);
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++) 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; *dstp = *srcp & *patp;
patp++; patp++;
@ -604,13 +604,10 @@ static BOOL BitBlt_PATCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi
} }
else else
{ {
/* align pattern to 8x8 grid to make sure transition
between different pattern blocks are smooth */
if (hdcDest->brush->style == GDI_BS_HATCHED) if (hdcDest->brush->style == GDI_BS_HATCHED)
{ {
xOffset = nXDest % 8; xOffset = 0;
yOffset = nYDest % 8 + 2; // +2 added after comparison to mstsc yOffset = 2; // +2 added after comparison to mstsc
} }
else 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++) 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; *dstp = *patp;
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++) 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; *dstp = *patp ^ *dstp;
patp++; 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++) 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)); *dstp = *dstp | (*patp | ~(*srcp));
patp++; patp++;

View File

@ -53,7 +53,7 @@ p_PatBlt PatBlt_[5] =
HGDI_BRUSH gdi_CreateSolidBrush(GDI_COLOR crColor) 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) if (!hBrush)
return NULL; return NULL;
hBrush->objectType = GDIOBJECT_BRUSH; hBrush->objectType = GDIOBJECT_BRUSH;
@ -71,7 +71,7 @@ HGDI_BRUSH gdi_CreateSolidBrush(GDI_COLOR crColor)
HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp) 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) if (!hBrush)
return NULL; return NULL;
hBrush->objectType = GDIOBJECT_BRUSH; hBrush->objectType = GDIOBJECT_BRUSH;
@ -82,7 +82,7 @@ HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp)
HGDI_BRUSH gdi_CreateHatchBrush(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) if (!hBrush)
return NULL; return NULL;
hBrush->objectType = GDIOBJECT_BRUSH; 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) INLINE BYTE* gdi_get_brush_pointer(HGDI_DC hdcBrush, int x, int y)
{ {
BYTE * p; 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; 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) if (x >= 0 && y >= 0)
{ {
x = x % hBmpBrush->width; x = (x + hBmpBrush->width - (hdcBrush->brush->nXOrg % hBmpBrush->width)) % hBmpBrush->width;
y = y % hBmpBrush->height; y = (y + hBmpBrush->height - (hdcBrush->brush->nYOrg % hBmpBrush->height)) % hBmpBrush->height;
p = hBmpBrush->data + (y * hBmpBrush->scanline) + (x * hBmpBrush->bytesPerPixel); p = hBmpBrush->data + (y * hBmpBrush->scanline) + (x * hBmpBrush->bytesPerPixel);
return p; return p;
} }
@ -666,6 +677,8 @@ static BOOL gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
ret = FALSE; ret = FALSE;
goto out_error; 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, if (!gdi_PatBlt(gdi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect,
patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop))) patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop)))
@ -724,6 +737,8 @@ static BOOL gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
ret = FALSE; ret = FALSE;
goto out_error; 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, if (!gdi_PatBlt(gdi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect,
patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop))) patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop)))
@ -957,6 +972,8 @@ static BOOL gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
gdi_DeleteObject((HGDIOBJECT) hBmp); gdi_DeleteObject((HGDIOBJECT) hBmp);
goto out_fail; 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, gdi_BitBlt(gdi->drawing->hdc, mem3blt->nLeftRect, mem3blt->nTopRect,
mem3blt->nWidth, mem3blt->nHeight, bitmap->hdc, mem3blt->nWidth, mem3blt->nHeight, bitmap->hdc,