gdiplus: Create gdi pen every time gdi+ pen is used.
This commit is contained in:
parent
c3e8af414b
commit
4c424b3c16
|
@ -46,7 +46,6 @@ struct GpPen{
|
|||
UINT style;
|
||||
GpUnit unit;
|
||||
REAL width;
|
||||
HPEN gdipen;
|
||||
GpLineCap endcap;
|
||||
GpLineCap startcap;
|
||||
GpDashCap dashcap;
|
||||
|
|
|
@ -72,6 +72,51 @@ static BYTE convert_path_point_type(BYTE type)
|
|||
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
|
||||
* order to be drawn on the device context. In the end, this should include at
|
||||
* least:
|
||||
|
@ -89,26 +134,7 @@ static void transform_and_round_points(GpGraphics *graphics, POINT *pti,
|
|||
GpMatrix *matrix;
|
||||
int i;
|
||||
|
||||
switch(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;
|
||||
}
|
||||
unitscale = convert_unit(graphics->hdc, graphics->unit);
|
||||
|
||||
/* apply page scale */
|
||||
if(graphics->unit != UnitDisplay)
|
||||
|
@ -125,21 +151,12 @@ static void transform_and_round_points(GpGraphics *graphics, POINT *pti,
|
|||
}
|
||||
|
||||
/* GdipDrawPie/GdipFillPie helper function */
|
||||
static GpStatus draw_pie(GpGraphics *graphics, HBRUSH gdibrush, HPEN gdipen,
|
||||
REAL x, REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle)
|
||||
static void draw_pie(GpGraphics *graphics, REAL x, REAL y, REAL width,
|
||||
REAL height, REAL startAngle, REAL sweepAngle)
|
||||
{
|
||||
INT save_state;
|
||||
GpPointF ptf[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].Y = y;
|
||||
ptf[1].X = x + width;
|
||||
|
@ -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,
|
||||
pti[2].y, pti[3].x, pti[3].y);
|
||||
|
||||
RestoreDC(graphics->hdc, save_state);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
/* GdipDrawCurve helper function.
|
||||
|
@ -798,13 +811,11 @@ GpStatus WINGDIPAPI GdipDrawArc(GpGraphics *graphics, GpPen *pen, REAL x,
|
|||
|
||||
num_pts = arc2polybezier(points, x, y, width, height, startAngle, sweepAngle);
|
||||
|
||||
save_state = SaveDC(graphics->hdc);
|
||||
EndPath(graphics->hdc);
|
||||
SelectObject(graphics->hdc, pen->gdipen);
|
||||
save_state = prepare_dc(graphics, pen);
|
||||
|
||||
retval = draw_polybezier(graphics, pen, points, num_pts, TRUE);
|
||||
|
||||
RestoreDC(graphics->hdc, save_state);
|
||||
restore_dc(graphics, save_state);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -828,13 +839,11 @@ GpStatus WINGDIPAPI GdipDrawBezier(GpGraphics *graphics, GpPen *pen, REAL x1,
|
|||
pt[3].X = x4;
|
||||
pt[3].Y = y4;
|
||||
|
||||
save_state = SaveDC(graphics->hdc);
|
||||
EndPath(graphics->hdc);
|
||||
SelectObject(graphics->hdc, pen->gdipen);
|
||||
save_state = prepare_dc(graphics, pen);
|
||||
|
||||
retval = draw_polybezier(graphics, pen, pt, 4, TRUE);
|
||||
|
||||
RestoreDC(graphics->hdc, save_state);
|
||||
restore_dc(graphics, save_state);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -882,14 +891,12 @@ GpStatus WINGDIPAPI GdipDrawCurve2(GpGraphics *graphics, GpPen *pen,
|
|||
pt[len_pt-1].X = points[count-1].X;
|
||||
pt[len_pt-1].Y = points[count-1].Y;
|
||||
|
||||
save_state = SaveDC(graphics->hdc);
|
||||
EndPath(graphics->hdc);
|
||||
SelectObject(graphics->hdc, pen->gdipen);
|
||||
save_state = prepare_dc(graphics, pen);
|
||||
|
||||
retval = draw_polybezier(graphics, pen, pt, len_pt, TRUE);
|
||||
|
||||
GdipFree(pt);
|
||||
RestoreDC(graphics->hdc, save_state);
|
||||
restore_dc(graphics, save_state);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -909,13 +916,11 @@ GpStatus WINGDIPAPI GdipDrawLineI(GpGraphics *graphics, GpPen *pen, INT x1,
|
|||
pt[1].X = (REAL)x2;
|
||||
pt[1].Y = (REAL)y2;
|
||||
|
||||
save_state = SaveDC(graphics->hdc);
|
||||
EndPath(graphics->hdc);
|
||||
SelectObject(graphics->hdc, pen->gdipen);
|
||||
save_state = prepare_dc(graphics, pen);
|
||||
|
||||
retval = draw_polyline(graphics, pen, pt, 2, TRUE);
|
||||
|
||||
RestoreDC(graphics->hdc, save_state);
|
||||
restore_dc(graphics, save_state);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -929,13 +934,11 @@ GpStatus WINGDIPAPI GdipDrawLines(GpGraphics *graphics, GpPen *pen, GDIPCONST
|
|||
if(!pen || !graphics || (count < 2))
|
||||
return InvalidParameter;
|
||||
|
||||
save_state = SaveDC(graphics->hdc);
|
||||
EndPath(graphics->hdc);
|
||||
SelectObject(graphics->hdc, pen->gdipen);
|
||||
save_state = prepare_dc(graphics, pen);
|
||||
|
||||
retval = draw_polyline(graphics, pen, points, count, TRUE);
|
||||
|
||||
RestoreDC(graphics->hdc, save_state);
|
||||
restore_dc(graphics, save_state);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -948,14 +951,12 @@ GpStatus WINGDIPAPI GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path)
|
|||
if(!pen || !graphics)
|
||||
return InvalidParameter;
|
||||
|
||||
save_state = SaveDC(graphics->hdc);
|
||||
EndPath(graphics->hdc);
|
||||
SelectObject(graphics->hdc, pen->gdipen);
|
||||
save_state = prepare_dc(graphics, pen);
|
||||
|
||||
retval = draw_poly(graphics, pen, path->pathdata.Points,
|
||||
path->pathdata.Types, path->pathdata.Count, TRUE);
|
||||
|
||||
RestoreDC(graphics->hdc, save_state);
|
||||
restore_dc(graphics, save_state);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -963,11 +964,19 @@ GpStatus WINGDIPAPI GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path)
|
|||
GpStatus WINGDIPAPI GdipDrawPie(GpGraphics *graphics, GpPen *pen, REAL x,
|
||||
REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle)
|
||||
{
|
||||
if(!pen)
|
||||
INT save_state;
|
||||
|
||||
if(!graphics || !pen)
|
||||
return InvalidParameter;
|
||||
|
||||
return draw_pie(graphics, GetStockObject(NULL_BRUSH), pen->gdipen, x, y,
|
||||
width, height, startAngle, sweepAngle);
|
||||
save_state = prepare_dc(graphics, pen);
|
||||
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,
|
||||
|
@ -978,14 +987,12 @@ GpStatus WINGDIPAPI GdipDrawRectangleI(GpGraphics *graphics, GpPen *pen, INT x,
|
|||
if(!pen || !graphics)
|
||||
return InvalidParameter;
|
||||
|
||||
save_state = SaveDC(graphics->hdc);
|
||||
EndPath(graphics->hdc);
|
||||
SelectObject(graphics->hdc, pen->gdipen);
|
||||
save_state = prepare_dc(graphics, pen);
|
||||
SelectObject(graphics->hdc, GetStockObject(NULL_BRUSH));
|
||||
|
||||
Rectangle(graphics->hdc, x, y, x + width, y + height);
|
||||
|
||||
RestoreDC(graphics->hdc, save_state);
|
||||
restore_dc(graphics, save_state);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -1025,11 +1032,21 @@ end:
|
|||
GpStatus WINGDIPAPI GdipFillPie(GpGraphics *graphics, GpBrush *brush, REAL x,
|
||||
REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle)
|
||||
{
|
||||
if(!brush)
|
||||
INT save_state;
|
||||
|
||||
if(!graphics || !brush)
|
||||
return InvalidParameter;
|
||||
|
||||
return draw_pie(graphics, brush->gdibrush, GetStockObject(NULL_PEN), x, y,
|
||||
width, height, startAngle, sweepAngle);
|
||||
save_state = SaveDC(graphics->hdc);
|
||||
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,
|
||||
|
|
|
@ -79,10 +79,6 @@ GpStatus WINGDIPAPI GdipClonePen(GpPen *pen, GpPen **clonepen)
|
|||
GdipCloneCustomLineCap(pen->customend, &(*clonepen)->customend);
|
||||
GdipCloneBrush(pen->brush, &(*clonepen)->brush);
|
||||
|
||||
(*clonepen)->gdipen = ExtCreatePen((*clonepen)->style,
|
||||
roundr((*clonepen)->width),
|
||||
&(*clonepen)->brush->lb, 0, NULL);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
|
@ -106,10 +102,7 @@ GpStatus WINGDIPAPI GdipCreatePen1(ARGB color, FLOAT width, GpUnit unit,
|
|||
gp_pen->dash = DashStyleSolid;
|
||||
GdipCreateSolidFill(color, (GpSolidFill **)(&gp_pen->brush));
|
||||
|
||||
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 {
|
||||
if(!((gp_pen->unit == UnitWorld) || (gp_pen->unit == UnitPixel))) {
|
||||
FIXME("UnitWorld, UnitPixel only supported units\n");
|
||||
GdipFree(gp_pen);
|
||||
return NotImplemented;
|
||||
|
@ -123,7 +116,6 @@ GpStatus WINGDIPAPI GdipCreatePen1(ARGB color, FLOAT width, GpUnit unit,
|
|||
GpStatus WINGDIPAPI GdipDeletePen(GpPen *pen)
|
||||
{
|
||||
if(!pen) return InvalidParameter;
|
||||
DeleteObject(pen->gdipen);
|
||||
|
||||
GdipDeleteBrush(pen->brush);
|
||||
GdipDeleteCustomLineCap(pen->customstart);
|
||||
|
@ -164,21 +156,11 @@ GpStatus WINGDIPAPI GdipGetPenDashStyle(GpPen *pen, GpDashStyle *dash)
|
|||
|
||||
GpStatus WINGDIPAPI GdipSetPenBrushFill(GpPen *pen, GpBrush *brush)
|
||||
{
|
||||
GpStatus retval;
|
||||
|
||||
if(!pen || !brush)
|
||||
return InvalidParameter;
|
||||
|
||||
GdipDeleteBrush(pen->brush);
|
||||
retval = 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;
|
||||
return GdipCloneBrush(brush, &pen->brush);
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipSetPenColor(GpPen *pen, ARGB argb)
|
||||
|
@ -229,14 +211,11 @@ GpStatus WINGDIPAPI GdipSetPenDashStyle(GpPen *pen, GpDashStyle dash)
|
|||
if(!pen)
|
||||
return InvalidParameter;
|
||||
|
||||
DeleteObject(pen->gdipen);
|
||||
pen->dash = dash;
|
||||
pen->style &= ~(PS_ALTERNATE | PS_SOLID | PS_DASH | PS_DOT | PS_DASHDOT |
|
||||
PS_DASHDOTDOT | PS_NULL | PS_USERSTYLE | PS_INSIDEFRAME);
|
||||
pen->style |= gdip_to_gdi_dash(dash);
|
||||
|
||||
pen->gdipen = ExtCreatePen(pen->style, (INT) pen->width, &pen->brush->lb, 0, NULL);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
|
@ -277,13 +256,10 @@ GpStatus WINGDIPAPI GdipSetPenLineJoin(GpPen *pen, GpLineJoin join)
|
|||
{
|
||||
if(!pen) return InvalidParameter;
|
||||
|
||||
DeleteObject(pen->gdipen);
|
||||
pen->join = join;
|
||||
pen->style &= ~(PS_JOIN_ROUND | PS_JOIN_BEVEL | PS_JOIN_MITER);
|
||||
pen->style |= gdip_to_gdi_join(join);
|
||||
|
||||
pen->gdipen = ExtCreatePen(pen->style, (INT) pen->width, &pen->brush->lb, 0, NULL);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue