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);
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;
}
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);
{
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++;
}
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;
}
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);
{
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++;
}
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;
}
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);
{
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++;
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}
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)
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;
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;