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:
parent
3d8c2d510b
commit
401787eeb8
@ -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);
|
||||
|
@ -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++;
|
||||
}
|
||||
|
@ -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++;
|
||||
}
|
||||
|
@ -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++;
|
||||
|
@ -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}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user