xfreerdp: reintroduce Polygon drawing

This commit is contained in:
Marc-André Moreau 2012-02-12 17:14:59 -05:00
parent 5617af901a
commit f7a71079dd
7 changed files with 235 additions and 16 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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));

View File

@ -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 */

View File

@ -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;

View File

@ -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;
}

View File

@ -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)