mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2025-01-07 16:03:51 +08:00
xfreerdp: reintroduce Polygon drawing
This commit is contained in:
parent
5617af901a
commit
f7a71079dd
@ -620,7 +620,175 @@ void xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
|
||||
|
||||
void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
|
||||
{
|
||||
printf("Mem3Blt\n");
|
||||
}
|
||||
|
||||
void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
|
||||
{
|
||||
int i, npoints;
|
||||
XPoint* points;
|
||||
uint32 brush_color;
|
||||
xfInfo* xfi = ((xfContext*) context)->xfi;
|
||||
|
||||
printf("PolygonSC\n");
|
||||
|
||||
xf_set_rop2(xfi, polygon_sc->bRop2);
|
||||
brush_color = freerdp_color_convert_rgb(polygon_sc->brushColor, xfi->srcBpp, 32, xfi->clrconv);
|
||||
|
||||
npoints = polygon_sc->numPoints + 1;
|
||||
points = xmalloc(sizeof(XPoint) * npoints);
|
||||
|
||||
points[0].x = polygon_sc->xStart;
|
||||
points[0].y = polygon_sc->yStart;
|
||||
|
||||
for (i = 0; i < polygon_sc->numPoints; i++)
|
||||
{
|
||||
points[i + 1].x = polygon_sc->points[i].x;
|
||||
points[i + 1].y = polygon_sc->points[i].y;
|
||||
}
|
||||
|
||||
switch (polygon_sc->fillMode)
|
||||
{
|
||||
case 1: /* alternate */
|
||||
XSetFillRule(xfi->display, xfi->gc, EvenOddRule);
|
||||
break;
|
||||
|
||||
case 2: /* winding */
|
||||
XSetFillRule(xfi->display, xfi->gc, WindingRule);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("PolygonSC unknown fillMode: %d\n", polygon_sc->fillMode);
|
||||
break;
|
||||
}
|
||||
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||
XSetForeground(xfi->display, xfi->gc, brush_color);
|
||||
|
||||
XFillPolygon(xfi->display, xfi->drawing, xfi->gc,
|
||||
points, npoints, Complex, CoordModePrevious);
|
||||
|
||||
if (xfi->drawing == xfi->primary)
|
||||
{
|
||||
XFillPolygon(xfi->display, xfi->drawable, xfi->gc,
|
||||
points, npoints, Complex, CoordModePrevious);
|
||||
}
|
||||
|
||||
XSetFunction(xfi->display, xfi->gc, GXcopy);
|
||||
xfree(points);
|
||||
}
|
||||
|
||||
void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
|
||||
{
|
||||
int i, npoints;
|
||||
XPoint* points;
|
||||
Pixmap pattern;
|
||||
rdpBrush* brush;
|
||||
uint32 foreColor;
|
||||
uint32 backColor;
|
||||
xfInfo* xfi = ((xfContext*) context)->xfi;
|
||||
|
||||
brush = &(polygon_cb->brush);
|
||||
xf_set_rop2(xfi, polygon_cb->bRop2);
|
||||
foreColor = freerdp_color_convert_rgb(polygon_cb->foreColor, xfi->srcBpp, 32, xfi->clrconv);
|
||||
backColor = freerdp_color_convert_rgb(polygon_cb->backColor, xfi->srcBpp, 32, xfi->clrconv);
|
||||
|
||||
npoints = polygon_cb->numPoints + 1;
|
||||
points = xmalloc(sizeof(XPoint) * npoints);
|
||||
|
||||
points[0].x = polygon_cb->xStart;
|
||||
points[0].y = polygon_cb->yStart;
|
||||
|
||||
for (i = 0; i < polygon_cb->numPoints; i++)
|
||||
{
|
||||
points[i + 1].x = polygon_cb->points[i].x;
|
||||
points[i + 1].y = polygon_cb->points[i].y;
|
||||
}
|
||||
|
||||
switch (polygon_cb->fillMode)
|
||||
{
|
||||
case 1: /* alternate */
|
||||
XSetFillRule(xfi->display, xfi->gc, EvenOddRule);
|
||||
break;
|
||||
|
||||
case 2: /* winding */
|
||||
XSetFillRule(xfi->display, xfi->gc, WindingRule);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("PolygonCB unknown fillMode: %d\n", polygon_cb->fillMode);
|
||||
break;
|
||||
}
|
||||
|
||||
if (brush->style == GDI_BS_PATTERN)
|
||||
{
|
||||
if (brush->bpp > 1)
|
||||
{
|
||||
pattern = xf_brush_new(xfi, 8, 8, brush->bpp, brush->data);
|
||||
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillTiled);
|
||||
XSetTile(xfi->display, xfi->gc, pattern);
|
||||
XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
|
||||
|
||||
XFillPolygon(xfi->display, xfi->drawing, xfi->gc,
|
||||
points, npoints, Complex, CoordModePrevious);
|
||||
|
||||
if (xfi->drawing == xfi->primary)
|
||||
{
|
||||
XFillPolygon(xfi->display, xfi->drawable, xfi->gc,
|
||||
points, npoints, Complex, CoordModePrevious);
|
||||
}
|
||||
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||
XSetTSOrigin(xfi->display, xfi->gc, 0, 0);
|
||||
XFreePixmap(xfi->display, pattern);
|
||||
}
|
||||
else
|
||||
{
|
||||
pattern = xf_mono_bitmap_new(xfi, 8, 8, brush->data);
|
||||
|
||||
XSetForeground(xfi->display, xfi->gc, backColor);
|
||||
XSetBackground(xfi->display, xfi->gc, foreColor);
|
||||
|
||||
if (polygon_cb->backMode == BACKMODE_TRANSPARENT)
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillStippled);
|
||||
else if (polygon_cb->backMode == BACKMODE_OPAQUE)
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillOpaqueStippled);
|
||||
|
||||
XSetStipple(xfi->display, xfi->gc, pattern);
|
||||
XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
|
||||
|
||||
XFillPolygon(xfi->display, xfi->drawing, xfi->gc,
|
||||
points, npoints, Complex, CoordModePrevious);
|
||||
|
||||
if (xfi->drawing == xfi->primary)
|
||||
{
|
||||
XFillPolygon(xfi->display, xfi->drawable, xfi->gc,
|
||||
points, npoints, Complex, CoordModePrevious);
|
||||
}
|
||||
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||
XSetTSOrigin(xfi->display, xfi->gc, 0, 0);
|
||||
XFreePixmap(xfi->display, pattern);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("unimplemented brush style:%d\n", brush->style);
|
||||
}
|
||||
|
||||
XSetFunction(xfi->display, xfi->gc, GXcopy);
|
||||
xfree(points);
|
||||
}
|
||||
|
||||
void xf_gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc)
|
||||
{
|
||||
printf("EllipseSC\n");
|
||||
}
|
||||
|
||||
void xf_gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb)
|
||||
{
|
||||
printf("EllipseCB\n");
|
||||
}
|
||||
|
||||
void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
|
||||
@ -777,10 +945,10 @@ void xf_gdi_register_update_callbacks(rdpUpdate* update)
|
||||
primary->GlyphIndex = NULL;
|
||||
primary->FastIndex = NULL;
|
||||
primary->FastGlyph = NULL;
|
||||
primary->PolygonSC = NULL;
|
||||
primary->PolygonCB = NULL;
|
||||
primary->EllipseSC = NULL;
|
||||
primary->EllipseCB = NULL;
|
||||
primary->PolygonSC = xf_gdi_polygon_sc;
|
||||
primary->PolygonCB = xf_gdi_polygon_cb;
|
||||
primary->EllipseSC = xf_gdi_ellipse_sc;
|
||||
primary->EllipseCB = xf_gdi_ellipse_cb;
|
||||
|
||||
update->SurfaceBits = xf_gdi_surface_bits;
|
||||
update->SurfaceFrameMarker = xf_gdi_surface_frame_marker;
|
||||
|
@ -502,8 +502,10 @@ boolean xf_pre_connect(freerdp* instance)
|
||||
settings->order_support[NEG_GLYPH_INDEX_INDEX] = true;
|
||||
settings->order_support[NEG_FAST_INDEX_INDEX] = true;
|
||||
settings->order_support[NEG_FAST_GLYPH_INDEX] = true;
|
||||
settings->order_support[NEG_POLYGON_SC_INDEX] = false;
|
||||
settings->order_support[NEG_POLYGON_CB_INDEX] = false;
|
||||
|
||||
settings->order_support[NEG_POLYGON_SC_INDEX] = (settings->sw_gdi) ? false : true;
|
||||
settings->order_support[NEG_POLYGON_CB_INDEX] = (settings->sw_gdi) ? false : true;
|
||||
|
||||
settings->order_support[NEG_ELLIPSE_SC_INDEX] = false;
|
||||
settings->order_support[NEG_ELLIPSE_CB_INDEX] = false;
|
||||
|
||||
|
@ -517,7 +517,7 @@ void test_read_polygon_cb_order(void)
|
||||
CU_ASSERT(polygon_cb.brush.x == 4);
|
||||
CU_ASSERT(polygon_cb.brush.y == 3);
|
||||
CU_ASSERT(polygon_cb.brush.style == 0x81);
|
||||
CU_ASSERT(polygon_cb.nDeltaEntries == 3);
|
||||
CU_ASSERT(polygon_cb.numPoints == 3);
|
||||
CU_ASSERT(polygon_cb.cbData == 5);
|
||||
|
||||
CU_ASSERT(stream_get_length(s) == (sizeof(polygon_cb_order) - 1));
|
||||
|
4
include/freerdp/cache/brush.h
vendored
4
include/freerdp/cache/brush.h
vendored
@ -41,7 +41,9 @@ struct rdp_brush_cache
|
||||
{
|
||||
pPatBlt PatBlt; /* 0 */
|
||||
pCacheBrush CacheBrush; /* 1 */
|
||||
uint32 paddingA[16 - 2]; /* 2 */
|
||||
pPolygonSC PolygonSC; /* 2 */
|
||||
pPolygonCB PolygonCB; /* 3 */
|
||||
uint32 paddingA[16 - 4]; /* 4 */
|
||||
|
||||
uint32 maxEntries; /* 16 */
|
||||
uint32 maxMonoEntries; /* 17 */
|
||||
|
@ -22,6 +22,9 @@
|
||||
|
||||
#include <freerdp/types.h>
|
||||
|
||||
#define BACKMODE_TRANSPARENT 0x0001
|
||||
#define BACKMODE_OPAQUE 0x0002
|
||||
|
||||
struct rdp_bounds
|
||||
{
|
||||
sint32 left;
|
||||
@ -365,9 +368,9 @@ struct _POLYGON_SC_ORDER
|
||||
uint32 bRop2;
|
||||
uint32 fillMode;
|
||||
uint32 brushColor;
|
||||
uint32 nDeltaEntries;
|
||||
uint32 numPoints;
|
||||
uint32 cbData;
|
||||
uint8* codeDeltaList;
|
||||
DELTA_POINT* points;
|
||||
};
|
||||
typedef struct _POLYGON_SC_ORDER POLYGON_SC_ORDER;
|
||||
|
||||
@ -376,13 +379,14 @@ struct _POLYGON_CB_ORDER
|
||||
sint32 xStart;
|
||||
sint32 yStart;
|
||||
uint32 bRop2;
|
||||
uint32 backMode;
|
||||
uint32 fillMode;
|
||||
uint32 backColor;
|
||||
uint32 foreColor;
|
||||
rdpBrush brush;
|
||||
uint32 nDeltaEntries;
|
||||
uint32 numPoints;
|
||||
uint32 cbData;
|
||||
uint8* codeDeltaList;
|
||||
DELTA_POINT* points;
|
||||
};
|
||||
typedef struct _POLYGON_CB_ORDER POLYGON_CB_ORDER;
|
||||
|
||||
|
@ -42,6 +42,30 @@ void update_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
|
||||
brush->style = style;
|
||||
}
|
||||
|
||||
void update_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
|
||||
{
|
||||
rdpCache* cache = context->cache;
|
||||
IFCALL(cache->brush->PolygonSC, context, polygon_sc);
|
||||
}
|
||||
|
||||
void update_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
|
||||
{
|
||||
uint8 style;
|
||||
rdpBrush* brush = &polygon_cb->brush;
|
||||
rdpCache* cache = context->cache;
|
||||
|
||||
style = brush->style;
|
||||
|
||||
if (brush->style & CACHED_BRUSH)
|
||||
{
|
||||
brush->data = brush_cache_get(cache->brush, brush->index, &brush->bpp);
|
||||
brush->style = 0x03;
|
||||
}
|
||||
|
||||
IFCALL(cache->brush->PolygonCB, context, polygon_cb);
|
||||
brush->style = style;
|
||||
}
|
||||
|
||||
void update_gdi_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cache_brush)
|
||||
{
|
||||
rdpCache* cache = context->cache;
|
||||
@ -127,8 +151,12 @@ void brush_cache_register_callbacks(rdpUpdate* update)
|
||||
rdpCache* cache = update->context->cache;
|
||||
|
||||
cache->brush->PatBlt = update->primary->PatBlt;
|
||||
cache->brush->PolygonSC = update->primary->PolygonSC;
|
||||
cache->brush->PolygonCB = update->primary->PolygonCB;
|
||||
|
||||
update->primary->PatBlt = update_gdi_patblt;
|
||||
update->primary->PolygonSC = update_gdi_polygon_sc;
|
||||
update->primary->PolygonCB = update_gdi_polygon_cb;
|
||||
update->secondary->CacheBrush = update_gdi_cache_brush;
|
||||
}
|
||||
|
||||
|
@ -1086,12 +1086,18 @@ void update_read_polygon_sc_order(STREAM* s, ORDER_INFO* orderInfo, POLYGON_SC_O
|
||||
update_read_color(s, &polygon_sc->brushColor);
|
||||
|
||||
if (orderInfo->fieldFlags & ORDER_FIELD_06)
|
||||
stream_read_uint8(s, polygon_sc->nDeltaEntries);
|
||||
stream_read_uint8(s, polygon_sc->numPoints);
|
||||
|
||||
if (orderInfo->fieldFlags & ORDER_FIELD_07)
|
||||
{
|
||||
stream_read_uint8(s, polygon_sc->cbData);
|
||||
stream_seek(s, polygon_sc->cbData);
|
||||
|
||||
if (polygon_sc->points == NULL)
|
||||
polygon_sc->points = (DELTA_POINT*) xmalloc(sizeof(DELTA_POINT) * polygon_sc->numPoints);
|
||||
else
|
||||
polygon_sc->points = (DELTA_POINT*) xrealloc(polygon_sc->points, sizeof(DELTA_POINT) * polygon_sc->numPoints);
|
||||
|
||||
update_read_delta_points(s, polygon_sc->points, polygon_sc->numPoints, polygon_sc->xStart, polygon_sc->yStart);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1118,13 +1124,22 @@ void update_read_polygon_cb_order(STREAM* s, ORDER_INFO* orderInfo, POLYGON_CB_O
|
||||
update_read_brush(s, &polygon_cb->brush, orderInfo->fieldFlags >> 6);
|
||||
|
||||
if (orderInfo->fieldFlags & ORDER_FIELD_12)
|
||||
stream_read_uint8(s, polygon_cb->nDeltaEntries);
|
||||
stream_read_uint8(s, polygon_cb->numPoints);
|
||||
|
||||
if (orderInfo->fieldFlags & ORDER_FIELD_13)
|
||||
{
|
||||
stream_read_uint8(s, polygon_cb->cbData);
|
||||
stream_seek(s, polygon_cb->cbData);
|
||||
|
||||
if (polygon_cb->points == NULL)
|
||||
polygon_cb->points = (DELTA_POINT*) xmalloc(sizeof(DELTA_POINT) * polygon_cb->numPoints);
|
||||
else
|
||||
polygon_cb->points = (DELTA_POINT*) xrealloc(polygon_cb->points, sizeof(DELTA_POINT) * polygon_cb->numPoints);
|
||||
|
||||
update_read_delta_points(s, polygon_cb->points, polygon_cb->numPoints, polygon_cb->xStart, polygon_cb->yStart);
|
||||
}
|
||||
|
||||
polygon_cb->backMode = (polygon_cb->bRop2 & 0x80) ? BACKMODE_TRANSPARENT : BACKMODE_OPAQUE;
|
||||
polygon_cb->bRop2 = (polygon_cb->bRop2 & 0x1F);
|
||||
}
|
||||
|
||||
void update_read_ellipse_sc_order(STREAM* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc)
|
||||
|
Loading…
Reference in New Issue
Block a user