Commit 4c424b3c authored by Evan Stade's avatar Evan Stade Committed by Alexandre Julliard

gdiplus: Create gdi pen every time gdi+ pen is used.

parent c3e8af41
...@@ -46,7 +46,6 @@ struct GpPen{ ...@@ -46,7 +46,6 @@ struct GpPen{
UINT style; UINT style;
GpUnit unit; GpUnit unit;
REAL width; REAL width;
HPEN gdipen;
GpLineCap endcap; GpLineCap endcap;
GpLineCap startcap; GpLineCap startcap;
GpDashCap dashcap; GpDashCap dashcap;
......
...@@ -72,6 +72,51 @@ static BYTE convert_path_point_type(BYTE type) ...@@ -72,6 +72,51 @@ static BYTE convert_path_point_type(BYTE type)
return ret; return ret;
} }
static REAL convert_unit(HDC hdc, GpUnit unit)
{
switch(unit)
{
case UnitInch:
return (REAL) GetDeviceCaps(hdc, LOGPIXELSX);
case UnitPoint:
return ((REAL)GetDeviceCaps(hdc, LOGPIXELSX)) / 72.0;
case UnitDocument:
return ((REAL)GetDeviceCaps(hdc, LOGPIXELSX)) / 300.0;
case UnitMillimeter:
return ((REAL)GetDeviceCaps(hdc, LOGPIXELSX)) / 25.4;
case UnitWorld:
ERR("cannot convert UnitWorld\n");
return 0.0;
case UnitPixel:
case UnitDisplay:
default:
return 1.0;
}
}
static INT prepare_dc(GpGraphics *graphics, GpPen *pen)
{
HPEN gdipen;
REAL width;
INT save_state = SaveDC(graphics->hdc);
EndPath(graphics->hdc);
width = pen->width * convert_unit(graphics->hdc,
pen->unit == UnitWorld ? graphics->unit : pen->unit);
gdipen = ExtCreatePen(pen->style, roundr(width), &pen->brush->lb, 0, NULL);
SelectObject(graphics->hdc, gdipen);
return save_state;
}
static void restore_dc(GpGraphics *graphics, INT state)
{
DeleteObject(SelectObject(graphics->hdc, GetStockObject(NULL_PEN)));
RestoreDC(graphics->hdc, state);
}
/* This helper applies all the changes that the points listed in ptf need in /* This helper applies all the changes that the points listed in ptf need in
* order to be drawn on the device context. In the end, this should include at * order to be drawn on the device context. In the end, this should include at
* least: * least:
...@@ -89,26 +134,7 @@ static void transform_and_round_points(GpGraphics *graphics, POINT *pti, ...@@ -89,26 +134,7 @@ static void transform_and_round_points(GpGraphics *graphics, POINT *pti,
GpMatrix *matrix; GpMatrix *matrix;
int i; int i;
switch(graphics->unit) unitscale = convert_unit(graphics->hdc, graphics->unit);
{
case UnitInch:
unitscale = GetDeviceCaps(graphics->hdc, LOGPIXELSX);
break;
case UnitPoint:
unitscale = ((REAL)GetDeviceCaps(graphics->hdc, LOGPIXELSX)) / 72.0;
break;
case UnitDocument:
unitscale = ((REAL)GetDeviceCaps(graphics->hdc, LOGPIXELSX)) / 300.0;
break;
case UnitMillimeter:
unitscale = ((REAL)GetDeviceCaps(graphics->hdc, LOGPIXELSX)) / 25.4;
break;
case UnitPixel:
case UnitDisplay:
default:
unitscale = 1.0;
break;
}
/* apply page scale */ /* apply page scale */
if(graphics->unit != UnitDisplay) if(graphics->unit != UnitDisplay)
...@@ -125,21 +151,12 @@ static void transform_and_round_points(GpGraphics *graphics, POINT *pti, ...@@ -125,21 +151,12 @@ static void transform_and_round_points(GpGraphics *graphics, POINT *pti,
} }
/* GdipDrawPie/GdipFillPie helper function */ /* GdipDrawPie/GdipFillPie helper function */
static GpStatus draw_pie(GpGraphics *graphics, HBRUSH gdibrush, HPEN gdipen, static void draw_pie(GpGraphics *graphics, REAL x, REAL y, REAL width,
REAL x, REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle) REAL height, REAL startAngle, REAL sweepAngle)
{ {
INT save_state;
GpPointF ptf[4]; GpPointF ptf[4];
POINT pti[4]; POINT pti[4];
if(!graphics)
return InvalidParameter;
save_state = SaveDC(graphics->hdc);
EndPath(graphics->hdc);
SelectObject(graphics->hdc, gdipen);
SelectObject(graphics->hdc, gdibrush);
ptf[0].X = x; ptf[0].X = x;
ptf[0].Y = y; ptf[0].Y = y;
ptf[1].X = x + width; ptf[1].X = x + width;
...@@ -152,10 +169,6 @@ static GpStatus draw_pie(GpGraphics *graphics, HBRUSH gdibrush, HPEN gdipen, ...@@ -152,10 +169,6 @@ static GpStatus draw_pie(GpGraphics *graphics, HBRUSH gdibrush, HPEN gdipen,
Pie(graphics->hdc, pti[0].x, pti[0].y, pti[1].x, pti[1].y, pti[2].x, Pie(graphics->hdc, pti[0].x, pti[0].y, pti[1].x, pti[1].y, pti[2].x,
pti[2].y, pti[3].x, pti[3].y); pti[2].y, pti[3].x, pti[3].y);
RestoreDC(graphics->hdc, save_state);
return Ok;
} }
/* GdipDrawCurve helper function. /* GdipDrawCurve helper function.
...@@ -798,13 +811,11 @@ GpStatus WINGDIPAPI GdipDrawArc(GpGraphics *graphics, GpPen *pen, REAL x, ...@@ -798,13 +811,11 @@ GpStatus WINGDIPAPI GdipDrawArc(GpGraphics *graphics, GpPen *pen, REAL x,
num_pts = arc2polybezier(points, x, y, width, height, startAngle, sweepAngle); num_pts = arc2polybezier(points, x, y, width, height, startAngle, sweepAngle);
save_state = SaveDC(graphics->hdc); save_state = prepare_dc(graphics, pen);
EndPath(graphics->hdc);
SelectObject(graphics->hdc, pen->gdipen);
retval = draw_polybezier(graphics, pen, points, num_pts, TRUE); retval = draw_polybezier(graphics, pen, points, num_pts, TRUE);
RestoreDC(graphics->hdc, save_state); restore_dc(graphics, save_state);
return retval; return retval;
} }
...@@ -828,13 +839,11 @@ GpStatus WINGDIPAPI GdipDrawBezier(GpGraphics *graphics, GpPen *pen, REAL x1, ...@@ -828,13 +839,11 @@ GpStatus WINGDIPAPI GdipDrawBezier(GpGraphics *graphics, GpPen *pen, REAL x1,
pt[3].X = x4; pt[3].X = x4;
pt[3].Y = y4; pt[3].Y = y4;
save_state = SaveDC(graphics->hdc); save_state = prepare_dc(graphics, pen);
EndPath(graphics->hdc);
SelectObject(graphics->hdc, pen->gdipen);
retval = draw_polybezier(graphics, pen, pt, 4, TRUE); retval = draw_polybezier(graphics, pen, pt, 4, TRUE);
RestoreDC(graphics->hdc, save_state); restore_dc(graphics, save_state);
return retval; return retval;
} }
...@@ -882,14 +891,12 @@ GpStatus WINGDIPAPI GdipDrawCurve2(GpGraphics *graphics, GpPen *pen, ...@@ -882,14 +891,12 @@ GpStatus WINGDIPAPI GdipDrawCurve2(GpGraphics *graphics, GpPen *pen,
pt[len_pt-1].X = points[count-1].X; pt[len_pt-1].X = points[count-1].X;
pt[len_pt-1].Y = points[count-1].Y; pt[len_pt-1].Y = points[count-1].Y;
save_state = SaveDC(graphics->hdc); save_state = prepare_dc(graphics, pen);
EndPath(graphics->hdc);
SelectObject(graphics->hdc, pen->gdipen);
retval = draw_polybezier(graphics, pen, pt, len_pt, TRUE); retval = draw_polybezier(graphics, pen, pt, len_pt, TRUE);
GdipFree(pt); GdipFree(pt);
RestoreDC(graphics->hdc, save_state); restore_dc(graphics, save_state);
return retval; return retval;
} }
...@@ -909,13 +916,11 @@ GpStatus WINGDIPAPI GdipDrawLineI(GpGraphics *graphics, GpPen *pen, INT x1, ...@@ -909,13 +916,11 @@ GpStatus WINGDIPAPI GdipDrawLineI(GpGraphics *graphics, GpPen *pen, INT x1,
pt[1].X = (REAL)x2; pt[1].X = (REAL)x2;
pt[1].Y = (REAL)y2; pt[1].Y = (REAL)y2;
save_state = SaveDC(graphics->hdc); save_state = prepare_dc(graphics, pen);
EndPath(graphics->hdc);
SelectObject(graphics->hdc, pen->gdipen);
retval = draw_polyline(graphics, pen, pt, 2, TRUE); retval = draw_polyline(graphics, pen, pt, 2, TRUE);
RestoreDC(graphics->hdc, save_state); restore_dc(graphics, save_state);
return retval; return retval;
} }
...@@ -929,13 +934,11 @@ GpStatus WINGDIPAPI GdipDrawLines(GpGraphics *graphics, GpPen *pen, GDIPCONST ...@@ -929,13 +934,11 @@ GpStatus WINGDIPAPI GdipDrawLines(GpGraphics *graphics, GpPen *pen, GDIPCONST
if(!pen || !graphics || (count < 2)) if(!pen || !graphics || (count < 2))
return InvalidParameter; return InvalidParameter;
save_state = SaveDC(graphics->hdc); save_state = prepare_dc(graphics, pen);
EndPath(graphics->hdc);
SelectObject(graphics->hdc, pen->gdipen);
retval = draw_polyline(graphics, pen, points, count, TRUE); retval = draw_polyline(graphics, pen, points, count, TRUE);
RestoreDC(graphics->hdc, save_state); restore_dc(graphics, save_state);
return retval; return retval;
} }
...@@ -948,14 +951,12 @@ GpStatus WINGDIPAPI GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path) ...@@ -948,14 +951,12 @@ GpStatus WINGDIPAPI GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path)
if(!pen || !graphics) if(!pen || !graphics)
return InvalidParameter; return InvalidParameter;
save_state = SaveDC(graphics->hdc); save_state = prepare_dc(graphics, pen);
EndPath(graphics->hdc);
SelectObject(graphics->hdc, pen->gdipen);
retval = draw_poly(graphics, pen, path->pathdata.Points, retval = draw_poly(graphics, pen, path->pathdata.Points,
path->pathdata.Types, path->pathdata.Count, TRUE); path->pathdata.Types, path->pathdata.Count, TRUE);
RestoreDC(graphics->hdc, save_state); restore_dc(graphics, save_state);
return retval; return retval;
} }
...@@ -963,11 +964,19 @@ GpStatus WINGDIPAPI GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path) ...@@ -963,11 +964,19 @@ GpStatus WINGDIPAPI GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path)
GpStatus WINGDIPAPI GdipDrawPie(GpGraphics *graphics, GpPen *pen, REAL x, GpStatus WINGDIPAPI GdipDrawPie(GpGraphics *graphics, GpPen *pen, REAL x,
REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle) REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle)
{ {
if(!pen) INT save_state;
if(!graphics || !pen)
return InvalidParameter; return InvalidParameter;
return draw_pie(graphics, GetStockObject(NULL_BRUSH), pen->gdipen, x, y, save_state = prepare_dc(graphics, pen);
width, height, startAngle, sweepAngle); SelectObject(graphics->hdc, GetStockObject(NULL_BRUSH));
draw_pie(graphics, x, y, width, height, startAngle, sweepAngle);
restore_dc(graphics, save_state);
return Ok;
} }
GpStatus WINGDIPAPI GdipDrawRectangleI(GpGraphics *graphics, GpPen *pen, INT x, GpStatus WINGDIPAPI GdipDrawRectangleI(GpGraphics *graphics, GpPen *pen, INT x,
...@@ -978,14 +987,12 @@ GpStatus WINGDIPAPI GdipDrawRectangleI(GpGraphics *graphics, GpPen *pen, INT x, ...@@ -978,14 +987,12 @@ GpStatus WINGDIPAPI GdipDrawRectangleI(GpGraphics *graphics, GpPen *pen, INT x,
if(!pen || !graphics) if(!pen || !graphics)
return InvalidParameter; return InvalidParameter;
save_state = SaveDC(graphics->hdc); save_state = prepare_dc(graphics, pen);
EndPath(graphics->hdc);
SelectObject(graphics->hdc, pen->gdipen);
SelectObject(graphics->hdc, GetStockObject(NULL_BRUSH)); SelectObject(graphics->hdc, GetStockObject(NULL_BRUSH));
Rectangle(graphics->hdc, x, y, x + width, y + height); Rectangle(graphics->hdc, x, y, x + width, y + height);
RestoreDC(graphics->hdc, save_state); restore_dc(graphics, save_state);
return Ok; return Ok;
} }
...@@ -1025,11 +1032,21 @@ end: ...@@ -1025,11 +1032,21 @@ end:
GpStatus WINGDIPAPI GdipFillPie(GpGraphics *graphics, GpBrush *brush, REAL x, GpStatus WINGDIPAPI GdipFillPie(GpGraphics *graphics, GpBrush *brush, REAL x,
REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle) REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle)
{ {
if(!brush) INT save_state;
if(!graphics || !brush)
return InvalidParameter; return InvalidParameter;
return draw_pie(graphics, brush->gdibrush, GetStockObject(NULL_PEN), x, y, save_state = SaveDC(graphics->hdc);
width, height, startAngle, sweepAngle); EndPath(graphics->hdc);
SelectObject(graphics->hdc, brush->gdibrush);
SelectObject(graphics->hdc, GetStockObject(NULL_PEN));
draw_pie(graphics, x, y, width, height, startAngle, sweepAngle);
RestoreDC(graphics->hdc, save_state);
return Ok;
} }
GpStatus WINGDIPAPI GdipFillPolygonI(GpGraphics *graphics, GpBrush *brush, GpStatus WINGDIPAPI GdipFillPolygonI(GpGraphics *graphics, GpBrush *brush,
......
...@@ -79,10 +79,6 @@ GpStatus WINGDIPAPI GdipClonePen(GpPen *pen, GpPen **clonepen) ...@@ -79,10 +79,6 @@ GpStatus WINGDIPAPI GdipClonePen(GpPen *pen, GpPen **clonepen)
GdipCloneCustomLineCap(pen->customend, &(*clonepen)->customend); GdipCloneCustomLineCap(pen->customend, &(*clonepen)->customend);
GdipCloneBrush(pen->brush, &(*clonepen)->brush); GdipCloneBrush(pen->brush, &(*clonepen)->brush);
(*clonepen)->gdipen = ExtCreatePen((*clonepen)->style,
roundr((*clonepen)->width),
&(*clonepen)->brush->lb, 0, NULL);
return Ok; return Ok;
} }
...@@ -106,10 +102,7 @@ GpStatus WINGDIPAPI GdipCreatePen1(ARGB color, FLOAT width, GpUnit unit, ...@@ -106,10 +102,7 @@ GpStatus WINGDIPAPI GdipCreatePen1(ARGB color, FLOAT width, GpUnit unit,
gp_pen->dash = DashStyleSolid; gp_pen->dash = DashStyleSolid;
GdipCreateSolidFill(color, (GpSolidFill **)(&gp_pen->brush)); GdipCreateSolidFill(color, (GpSolidFill **)(&gp_pen->brush));
if((gp_pen->unit == UnitWorld) || (gp_pen->unit == UnitPixel)) { if(!((gp_pen->unit == UnitWorld) || (gp_pen->unit == UnitPixel))) {
gp_pen->gdipen = ExtCreatePen(gp_pen->style, (INT) gp_pen->width,
&gp_pen->brush->lb, 0, NULL);
} else {
FIXME("UnitWorld, UnitPixel only supported units\n"); FIXME("UnitWorld, UnitPixel only supported units\n");
GdipFree(gp_pen); GdipFree(gp_pen);
return NotImplemented; return NotImplemented;
...@@ -123,7 +116,6 @@ GpStatus WINGDIPAPI GdipCreatePen1(ARGB color, FLOAT width, GpUnit unit, ...@@ -123,7 +116,6 @@ GpStatus WINGDIPAPI GdipCreatePen1(ARGB color, FLOAT width, GpUnit unit,
GpStatus WINGDIPAPI GdipDeletePen(GpPen *pen) GpStatus WINGDIPAPI GdipDeletePen(GpPen *pen)
{ {
if(!pen) return InvalidParameter; if(!pen) return InvalidParameter;
DeleteObject(pen->gdipen);
GdipDeleteBrush(pen->brush); GdipDeleteBrush(pen->brush);
GdipDeleteCustomLineCap(pen->customstart); GdipDeleteCustomLineCap(pen->customstart);
...@@ -164,21 +156,11 @@ GpStatus WINGDIPAPI GdipGetPenDashStyle(GpPen *pen, GpDashStyle *dash) ...@@ -164,21 +156,11 @@ GpStatus WINGDIPAPI GdipGetPenDashStyle(GpPen *pen, GpDashStyle *dash)
GpStatus WINGDIPAPI GdipSetPenBrushFill(GpPen *pen, GpBrush *brush) GpStatus WINGDIPAPI GdipSetPenBrushFill(GpPen *pen, GpBrush *brush)
{ {
GpStatus retval;
if(!pen || !brush) if(!pen || !brush)
return InvalidParameter; return InvalidParameter;
GdipDeleteBrush(pen->brush); GdipDeleteBrush(pen->brush);
retval = GdipCloneBrush(brush, &pen->brush); return GdipCloneBrush(brush, &pen->brush);
if(retval != Ok)
return retval;
DeleteObject(pen->gdipen);
pen->gdipen = ExtCreatePen(pen->style, roundr(pen->width), &pen->brush->lb, 0,
NULL);
return Ok;
} }
GpStatus WINGDIPAPI GdipSetPenColor(GpPen *pen, ARGB argb) GpStatus WINGDIPAPI GdipSetPenColor(GpPen *pen, ARGB argb)
...@@ -229,14 +211,11 @@ GpStatus WINGDIPAPI GdipSetPenDashStyle(GpPen *pen, GpDashStyle dash) ...@@ -229,14 +211,11 @@ GpStatus WINGDIPAPI GdipSetPenDashStyle(GpPen *pen, GpDashStyle dash)
if(!pen) if(!pen)
return InvalidParameter; return InvalidParameter;
DeleteObject(pen->gdipen);
pen->dash = dash; pen->dash = dash;
pen->style &= ~(PS_ALTERNATE | PS_SOLID | PS_DASH | PS_DOT | PS_DASHDOT | pen->style &= ~(PS_ALTERNATE | PS_SOLID | PS_DASH | PS_DOT | PS_DASHDOT |
PS_DASHDOTDOT | PS_NULL | PS_USERSTYLE | PS_INSIDEFRAME); PS_DASHDOTDOT | PS_NULL | PS_USERSTYLE | PS_INSIDEFRAME);
pen->style |= gdip_to_gdi_dash(dash); pen->style |= gdip_to_gdi_dash(dash);
pen->gdipen = ExtCreatePen(pen->style, (INT) pen->width, &pen->brush->lb, 0, NULL);
return Ok; return Ok;
} }
...@@ -277,13 +256,10 @@ GpStatus WINGDIPAPI GdipSetPenLineJoin(GpPen *pen, GpLineJoin join) ...@@ -277,13 +256,10 @@ GpStatus WINGDIPAPI GdipSetPenLineJoin(GpPen *pen, GpLineJoin join)
{ {
if(!pen) return InvalidParameter; if(!pen) return InvalidParameter;
DeleteObject(pen->gdipen);
pen->join = join; pen->join = join;
pen->style &= ~(PS_JOIN_ROUND | PS_JOIN_BEVEL | PS_JOIN_MITER); pen->style &= ~(PS_JOIN_ROUND | PS_JOIN_BEVEL | PS_JOIN_MITER);
pen->style |= gdip_to_gdi_join(join); pen->style |= gdip_to_gdi_join(join);
pen->gdipen = ExtCreatePen(pen->style, (INT) pen->width, &pen->brush->lb, 0, NULL);
return Ok; return Ok;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment