static void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) { BYTE* data; rdpBrush* brush; UINT32 foreColor; UINT32 backColor; GDI_COLOR originalColor; HGDI_BRUSH originalBrush; rdpGdi* gdi = context->gdi; brush = &patblt->brush; foreColor = freerdp_convert_gdi_order_color(patblt->foreColor, gdi->srcBpp, gdi->format, gdi->palette); backColor = freerdp_convert_gdi_order_color(patblt->backColor, gdi->srcBpp, gdi->format, gdi->palette); originalColor = gdi_SetTextColor(gdi->drawing->hdc, foreColor); if (brush->style == GDI_BS_SOLID) { originalBrush = gdi->drawing->hdc->brush; gdi->drawing->hdc->brush = gdi_CreateSolidBrush(foreColor); 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_HATCHED) { BYTE* hatched; HGDI_BITMAP hBmp; data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16); hatched = GDI_BS_HATCHED_PATTERNS + (8 * brush->hatch); freerdp_image_copy_from_monochrome(data, gdi->format, -1, 0, 0, 8, 8, hatched, backColor, foreColor, gdi->palette); 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; UINT32 brushFormat; if (brush->bpp > 1) { brushFormat = gdi_get_pixel_format(brush->bpp, FALSE); data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16); freerdp_image_copy(data, gdi->format, -1, 0, 0, 8, 8, brush->data, brushFormat, -1, 0, 0, gdi->palette); } else { data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16); freerdp_image_copy_from_monochrome(data, gdi->format, -1, 0, 0, 8, 8, brush->data, backColor, foreColor, gdi->palette); } hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data); originalBrush = gdi->drawing->hdc->brush; gdi->drawing->hdc->brush = gdi_CreatePatternBrush(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 { WLog_ERR(TAG, "unimplemented brush style:%d", brush->style); } gdi_SetTextColor(gdi->drawing->hdc, originalColor); }
static BOOL gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) { const rdpBrush* brush = &patblt->brush; UINT32 foreColor; UINT32 backColor; UINT32 originalColor; HGDI_BRUSH originalBrush, hbrush = NULL; rdpGdi* gdi = context->gdi; BOOL ret = FALSE; const DWORD rop = gdi_rop3_code(patblt->bRop); UINT32 nXSrc = 0; UINT32 nYSrc = 0; BYTE data[8 * 8 * 4]; HGDI_BITMAP hBmp = NULL; if (!gdi_decode_color(gdi, patblt->foreColor, &foreColor, NULL)) return FALSE; if (!gdi_decode_color(gdi, patblt->backColor, &backColor, NULL)) return FALSE; originalColor = gdi_SetTextColor(gdi->drawing->hdc, foreColor); originalBrush = gdi->drawing->hdc->brush; switch (brush->style) { case GDI_BS_SOLID: hbrush = gdi_CreateSolidBrush(foreColor); break; case GDI_BS_HATCHED: { const BYTE* hatched; hatched = GDI_BS_HATCHED_PATTERNS + (8 * brush->hatch); if (!freerdp_image_copy_from_monochrome(data, gdi->drawing->hdc->format, 0, 0, 0, 8, 8, hatched, backColor, foreColor, &gdi->palette)) goto out_error; hBmp = gdi_CreateBitmapEx(8, 8, gdi->drawing->hdc->format, 0, data, NULL); if (!hBmp) goto out_error; hbrush = gdi_CreateHatchBrush(hBmp); } break; case GDI_BS_PATTERN: { UINT32 brushFormat; if (brush->bpp > 1) { brushFormat = gdi_get_pixel_format(brush->bpp); if (!freerdp_image_copy(data, gdi->drawing->hdc->format, 0, 0, 0, 8, 8, brush->data, brushFormat, 0, 0, 0, &gdi->palette, FREERDP_FLIP_NONE)) goto out_error; } else { if (!freerdp_image_copy_from_monochrome(data, gdi->drawing->hdc->format, 0, 0, 0, 8, 8, brush->data, backColor, foreColor, &gdi->palette)) goto out_error; } hBmp = gdi_CreateBitmapEx(8, 8, gdi->drawing->hdc->format, 0, data, NULL); if (!hBmp) goto out_error; hbrush = gdi_CreatePatternBrush(hBmp); } break; default: WLog_ERR(TAG, "unimplemented brush style:%"PRIu32"", brush->style); break; } if (!hbrush) gdi_DeleteObject((HGDIOBJECT) hBmp); else { hbrush->nXOrg = brush->x; hbrush->nYOrg = brush->y; gdi->drawing->hdc->brush = hbrush; ret = gdi_BitBlt(gdi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight, gdi->primary->hdc, nXSrc, nYSrc, rop, &gdi->palette); } out_error: gdi_DeleteObject((HGDIOBJECT) hbrush); gdi->drawing->hdc->brush = originalBrush; gdi_SetTextColor(gdi->drawing->hdc, originalColor); return ret; }