libfreerdp-gdi: added brush style BS_HATCHED

according to [MS-RDPEGDI] 2.2.2.2.1.1.2.3 PatBlt (PATBLT_ORDER)
	16bit and 8bit colour depth are drawn with wrong background colour
This commit is contained in:
Christian Landvogt 2013-02-04 15:58:22 +01:00
parent 3d8c2d510b
commit 401787eeb8
6 changed files with 84 additions and 7 deletions

View File

@ -25,6 +25,7 @@
FREERDP_API HGDI_BRUSH gdi_CreateSolidBrush(GDI_COLOR crColor);
FREERDP_API HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp);
FREERDP_API HGDI_BRUSH gdi_CreateHatchBrush(HGDI_BITMAP hbmp);
FREERDP_API int gdi_PatBlt(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop);
typedef int (*p_PatBlt)(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop);

View File

@ -622,7 +622,7 @@ static int BitBlt_MERGEPAINT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int
static int BitBlt_PATCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
{
int x, y;
int x, y, xOffset, yOffset;
UINT16* dstp;
UINT16* patp;
UINT16 color16;
@ -647,6 +647,19 @@ static int BitBlt_PATCOPY_16bpp(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
}
else
{
xOffset = 0;
yOffset = 0;
}
for (y = 0; y < nHeight; y++)
{
dstp = (UINT16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
@ -655,7 +668,7 @@ static int BitBlt_PATCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, x+xOffset, y+yOffset);
*dstp = *patp;
dstp++;
}

View File

@ -664,7 +664,7 @@ static int BitBlt_MERGEPAINT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int
static int BitBlt_PATCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
{
int x, y;
int x, y, xOffset, yOffset;
UINT32* dstp;
UINT32* patp;
UINT32 color32;
@ -689,6 +689,19 @@ static int BitBlt_PATCOPY_32bpp(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
}
else
{
xOffset = 0;
yOffset = 0;
}
for (y = 0; y < nHeight; y++)
{
dstp = (UINT32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
@ -697,7 +710,7 @@ static int BitBlt_PATCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, x+xOffset, y+yOffset);
*dstp = *patp;
dstp++;
}

View File

@ -536,7 +536,7 @@ static int BitBlt_MERGEPAINT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int n
static int BitBlt_PATCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
{
int x, y;
int x, y, xOffset, yOffset;
BYTE* dstp;
BYTE* patp;
BYTE palIndex;
@ -559,6 +559,19 @@ static int BitBlt_PATCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWid
}
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
}
else
{
xOffset = 0;
yOffset = 0;
}
for (y = 0; y < nHeight; y++)
{
dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
@ -567,7 +580,7 @@ static int BitBlt_PATCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWid
{
for (x = 0; x < nWidth; x++)
{
patp = gdi_get_brush_pointer(hdcDest, x, y);
patp = gdi_get_brush_pointer(hdcDest, x+xOffset, y+yOffset);
*dstp = *patp;
patp++;

View File

@ -77,6 +77,15 @@ HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp)
return hBrush;
}
HGDI_BRUSH gdi_CreateHatchBrush(HGDI_BITMAP hbmp)
{
HGDI_BRUSH hBrush = (HGDI_BRUSH) malloc(sizeof(GDI_BRUSH));
hBrush->objectType = GDIOBJECT_BRUSH;
hBrush->style = GDI_BS_HATCHED;
hBrush->pattern = hbmp;
return hBrush;
}
/**
* Perform a pattern blit operation on the given pixel buffer.\n
* @msdn{dd162778}

View File

@ -312,6 +312,16 @@ static const UINT32 rop3_code_table[] =
0x00FF0062 /* 1 */
};
/* Hatch Patterns as monochrome data */
static BYTE GDI_BS_HACHTED_PATTERNS[] = {
0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, /* HS_HORIZONTAL */
0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, /* HS_VERTICAL */
0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F, /* HS_FDIAGONAL */
0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE, /* HS_BDIAGONAL */
0xF7, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0xF7, 0xF7, /* HS_CROSS */
0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E /* HS_DIACROSS */
};
/* GDI Helper Functions */
INLINE UINT32 gdi_rop3_code(BYTE code)
@ -342,7 +352,7 @@ INLINE BYTE* gdi_get_brush_pointer(HGDI_DC hdcBrush, int x, int y)
if (hdcBrush->brush != NULL)
{
if (hdcBrush->brush->style == GDI_BS_PATTERN)
if ((hdcBrush->brush->style == GDI_BS_PATTERN) || (hdcBrush->brush->style == GDI_BS_HATCHED))
{
HGDI_BITMAP hBmpBrush = hdcBrush->brush->pattern;
@ -489,6 +499,24 @@ void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
gdi->drawing->hdc->brush = originalBrush;
}
else if (brush->style == GDI_BS_HATCHED)
{
HGDI_BITMAP hBmp;
data = freerdp_mono_image_convert(GDI_BS_HACHTED_PATTERNS + 8 * brush->hatch, 8, 8, 1,
gdi->dstBpp, patblt->backColor, patblt->foreColor, gdi->clrconv);
hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data);
originalBrush = gdi->drawing->hdc->brush;
gdi->drawing->hdc->brush = gdi_CreateHatchBrush(hBmp);
gdi_PatBlt(gdi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect,
patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop));
gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
gdi->drawing->hdc->brush = originalBrush;
}
else if (brush->style == GDI_BS_PATTERN)
{
HGDI_BITMAP hBmp;