Merge pull request #951 from bailli/brushfix
X11 and libfreerdp-gdi: Added brush style BS_HATCHED
This commit is contained in:
commit
5a7f2d4d62
@ -33,6 +33,15 @@
|
|||||||
|
|
||||||
#include "xf_gdi.h"
|
#include "xf_gdi.h"
|
||||||
|
|
||||||
|
static UINT8 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 */
|
||||||
|
};
|
||||||
|
|
||||||
static const BYTE xf_rop2_table[] =
|
static const BYTE xf_rop2_table[] =
|
||||||
{
|
{
|
||||||
0,
|
0,
|
||||||
@ -349,6 +358,21 @@ void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
|
|||||||
XFillRectangle(xfi->display, xfi->drawing, xfi->gc,
|
XFillRectangle(xfi->display, xfi->drawing, xfi->gc,
|
||||||
patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight);
|
patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight);
|
||||||
}
|
}
|
||||||
|
else if (brush->style == GDI_BS_HATCHED)
|
||||||
|
{
|
||||||
|
pattern = xf_mono_bitmap_new(xfi, 8, 8, GDI_BS_HACHTED_PATTERNS + 8 * brush->hatch);
|
||||||
|
|
||||||
|
XSetForeground(xfi->display, xfi->gc, backColor);
|
||||||
|
XSetBackground(xfi->display, xfi->gc, foreColor);
|
||||||
|
XSetFillStyle(xfi->display, xfi->gc, FillOpaqueStippled);
|
||||||
|
XSetStipple(xfi->display, xfi->gc, pattern);
|
||||||
|
XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
|
||||||
|
|
||||||
|
XFillRectangle(xfi->display, xfi->drawing, xfi->gc,
|
||||||
|
patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight);
|
||||||
|
|
||||||
|
XFreePixmap(xfi->display, pattern);
|
||||||
|
}
|
||||||
else if (brush->style == GDI_BS_PATTERN)
|
else if (brush->style == GDI_BS_PATTERN)
|
||||||
{
|
{
|
||||||
if (brush->bpp > 1)
|
if (brush->bpp > 1)
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
FREERDP_API HGDI_BRUSH gdi_CreateSolidBrush(GDI_COLOR crColor);
|
FREERDP_API HGDI_BRUSH gdi_CreateSolidBrush(GDI_COLOR crColor);
|
||||||
FREERDP_API HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp);
|
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);
|
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);
|
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)
|
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* dstp;
|
||||||
UINT16* patp;
|
UINT16* patp;
|
||||||
UINT16 color16;
|
UINT16 color16;
|
||||||
@ -647,6 +647,19 @@ static int BitBlt_PATCOPY_16bpp(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)
|
||||||
|
{
|
||||||
|
xOffset = nXDest % 8;
|
||||||
|
yOffset = nYDest % 8 + 2; // +2 added after comparison to mstsc
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xOffset = 0;
|
||||||
|
yOffset = 0;
|
||||||
|
}
|
||||||
for (y = 0; y < nHeight; y++)
|
for (y = 0; y < nHeight; y++)
|
||||||
{
|
{
|
||||||
dstp = (UINT16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + 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++)
|
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 = *patp;
|
||||||
dstp++;
|
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)
|
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* dstp;
|
||||||
UINT32* patp;
|
UINT32* patp;
|
||||||
UINT32 color32;
|
UINT32 color32;
|
||||||
@ -689,6 +689,19 @@ static int BitBlt_PATCOPY_32bpp(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)
|
||||||
|
{
|
||||||
|
xOffset = nXDest % 8;
|
||||||
|
yOffset = nYDest % 8 + 2; // +2 added after comparison to mstsc
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xOffset = 0;
|
||||||
|
yOffset = 0;
|
||||||
|
}
|
||||||
for (y = 0; y < nHeight; y++)
|
for (y = 0; y < nHeight; y++)
|
||||||
{
|
{
|
||||||
dstp = (UINT32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + 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++)
|
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 = *patp;
|
||||||
dstp++;
|
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)
|
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* dstp;
|
||||||
BYTE* patp;
|
BYTE* patp;
|
||||||
BYTE palIndex;
|
BYTE palIndex;
|
||||||
@ -559,6 +559,19 @@ static int BitBlt_PATCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWid
|
|||||||
}
|
}
|
||||||
else
|
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++)
|
for (y = 0; y < nHeight; y++)
|
||||||
{
|
{
|
||||||
dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + 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++)
|
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;
|
*dstp = *patp;
|
||||||
patp++;
|
patp++;
|
||||||
|
@ -77,6 +77,15 @@ HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp)
|
|||||||
return hBrush;
|
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
|
* Perform a pattern blit operation on the given pixel buffer.\n
|
||||||
* @msdn{dd162778}
|
* @msdn{dd162778}
|
||||||
|
@ -312,6 +312,16 @@ static const UINT32 rop3_code_table[] =
|
|||||||
0x00FF0062 /* 1 */
|
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 */
|
/* GDI Helper Functions */
|
||||||
|
|
||||||
INLINE UINT32 gdi_rop3_code(BYTE code)
|
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 != 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;
|
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_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
|
||||||
gdi->drawing->hdc->brush = originalBrush;
|
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)
|
else if (brush->style == GDI_BS_PATTERN)
|
||||||
{
|
{
|
||||||
HGDI_BITMAP hBmp;
|
HGDI_BITMAP hBmp;
|
||||||
|
Loading…
Reference in New Issue
Block a user