More Direct2D path work.

This commit is contained in:
Pietro Gagliardi 2015-10-06 19:56:38 -04:00
parent 020e128a2c
commit de08c3a202
2 changed files with 99 additions and 60 deletions

View File

@ -66,13 +66,10 @@ ID2D1HwndRenderTarget *makeHWNDRenderTarget(HWND hwnd)
return rt; return rt;
} }
// TODO move below the path stuff
struct uiDrawContext { struct uiDrawContext {
ID2D1RenderTarget *rt; ID2D1RenderTarget *rt;
ID2D1PathGeometry *path;
ID2D1GeometrySink *sink;
BOOL inFigure;
// source color // source color
BOOL useRGB; BOOL useRGB;
uint8_t r; uint8_t r;
@ -115,82 +112,121 @@ void uiDrawBeginPathRGBA(uiDrawContext *c, uint8_t r, uint8_t g, uint8_t b, uint
c->inFigure = FALSE; c->inFigure = FALSE;
} }
void uiDrawMoveTo(uiDrawContext *c, intmax_t x, intmax_t y) struct uiDrawPath {
{ ID2D1PathGeometry *path;
D2D1_POINT_2F p; ID2D1GeometrySink *sink;
BOOL inFigure;
};
if (c->inFigure) uiDrawPath *uiDrawNewPath(uiDrawFillMode fillmode)
{
uiDrawPath *p;
HRESULT hr;
// TODO uiNew
p = malloc(sizeof (uiDrawPath));
hr = ID2D1Factory_CreatePathGeometry(d2dfactory,
&(p->path));
// TODO make sure this is the only success code
if (hr != S_OK)
logHRESULT("error creating path in uiDrawNewPath()", hr);
hr = ID2D1PathGeometry_Open(p->path,
&(p->sink));
if (hr != S_OK)
logHRESULT("error opening path in uiDrawNewPath()", hr);
switch (fillmode) {
case uiDrawFIllModeWinding:
ID2D1GeometrySink_SetFillMode(s->sink,
D2D1_FILL_MODE_WINDING);
break;
case uiDrawFillModeAlternate:
ID2D1GeometrySink_SetFillMode(s->sink,
D2D1_FILL_MODE_ALTERNATE);
break;
}
p->inFigure = FALSE;
return p;
}
void uiDrawFreePath(uiDrawPath *p)
{
if (p->inFigure)
ID2D1GeometrySink_EndFigure(p->sink,
D2D1_FIGURE_END_OPEN);
if (p->sink != NULL)
// TODO close sink first?
ID2D1GeometrySink_Release(p->sink);
ID2D1PathGeometry_Release(p->path);
// TODO uiFree
free(p);
}
void uiDrawPathNewFigure(uiDrawPath *p, double x, double y)
{
D2D1_POINT_2F pt;
if (p->inFigure)
ID2D1GeometrySink_EndFigure(c->sink, ID2D1GeometrySink_EndFigure(c->sink,
D2D1_FIGURE_END_OPEN); D2D1_FIGURE_END_OPEN);
p.x = ((FLOAT) x) + 0.5; p.x = x;
p.y = ((FLOAT) y) + 0.5; p.y = y;
ID2D1GeometrySink_BeginFigure(c->sink, ID2D1GeometrySink_BeginFigure(p->sink,
p, pt,
D2D1_FIGURE_BEGIN_FILLED); D2D1_FIGURE_BEGIN_FILLED);
c->inFigure = TRUE; p->inFigure = TRUE;
} }
void uiDrawLineTo(uiDrawContext *c, intmax_t x, intmax_t y) void uiDrawPathLineTo(uiDrawPath *p, double x, double y)
{ {
D2D1_POINT_2F p; D2D1_POINT_2F pt;
p.x = ((FLOAT) x) + 0.5; pt.x = x;
p.y = ((FLOAT) y) + 0.5; pt.y = y;
ID2D1GeometrySink_AddLine(c->sink, p); ID2D1GeometrySink_AddLine(p->sink, pt);
} }
void uiDrawRectangle(uiDrawContext *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height) void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double endAngle)
{ {
// TODO // TODO
} }
void uiDrawArcTo(uiDrawContext *c, intmax_t xCenter, intmax_t yCenter, intmax_t radius, double startAngle, double endAngle, int lineFromCurrentPointToStart) void uiDrawPathBezierTo(uiDrawPath *p, double c1x, double c1y, double c2x, double c2y, double endX, double endY)
{ {
if (!lineFromCurrentPointToStart) { D2D1_BEZIER_SEGMENT s;
int bx, by, bx2, by2;
int sx, sy, ex, ey;
// see http://stackoverflow.com/questions/32465446/how-do-i-inhibit-the-initial-line-segment-of-an-anglearc s.point1.x = c1x;
// the idea for floor(x + 0.5) is inspired by wine s.point1.y = c1y;
// TODO make sure this is an accurate imitation of AngleArc() s.point2.x = c2x;
bx = xCenter - radius; s.point2.y = c2y;
by = yCenter - radius; s.point3.x = endX;
bx2 = xCenter + radius; s.point3.y = endY;
by2 = yCenter + radius; ID2D1GeometrySink_AddBezier(p->sink, &s);
sx = xCenter + floor((double) radius * cos(startAngle));
sy = yCenter - floor((double) radius * sin(startAngle));
ex = xCenter + floor((double) radius * cos(endAngle));
ey = yCenter - floor((double) radius * sin(endAngle));
/* TODO
if (Arc(c->dc, bx, by, bx2, by2, sx, sy, ex, ey) == 0)
logLastError("error drawing current point arc in uiDrawArc()");
return;
*/
}
/* TODO
// AngleArc() expects degrees
startAngle *= (180.0 / M_PI);
endAngle *= (180.0 / M_PI);
if (AngleArc(c->dc,
xCenter, yCenter,
radius,
startAngle,
// the "sweep angle" is relative to the start angle, not to 0
endAngle - startAngle) == 0)
logLastError("error drawing arc in uiDrawArc()");
*/
} }
void uiDrawBezierTo(uiDrawContext *c, intmax_t c1x, intmax_t c1y, intmax_t c2x, intmax_t c2y, intmax_t endX, intmax_t endY) void uiDrawPathCloseFigure(uiDrawPath *p)
{ {
// TODO ID2D1GeometrySink_EndFigure(p->sink,
}
void uiDrawCloseFigure(uiDrawContext *c)
{
ID2D1GeometrySink_EndFigure(c->sink,
D2D1_FIGURE_END_CLOSED); D2D1_FIGURE_END_CLOSED);
c->inFigure = FALSE; p->inFigure = FALSE;
}
void uiDrawPathAddRectangle(uiDrawPath *p, double x0, double y0, double xxxxTODOxxxx, double xxxTODOxxxxxxxxxx)
{
// TODO
}
void uiDrawPathEnd(uiDrawPath *p)
{
HRESULT hr;
if (p->inFigure)
ID2D1GeometrySink_EndFigure(c->sink,
D2D1_FIGURE_END_OPEN);
hr = ID2D1GeometrySink_Close(p->sink);
if (hr != S_OK)
logHRESULT("error closing path in uiDrawPathEnd()", hr);
ID2D1GeometrySink_Release(p->sink);
p->sink = NULL;
} }
static ID2D1SolidColorBrush *makeBrush(uiDrawContext *c) static ID2D1SolidColorBrush *makeBrush(uiDrawContext *c)

View File

@ -75,13 +75,16 @@ struct uiDrawStrokeParams {
}; };
uiDrawPath *uiDrawNewPath(uiDrawFillMode); uiDrawPath *uiDrawNewPath(uiDrawFillMode);
void uiDrawFreePath(uiDrawPath *);
void uiDrawPathNewFigure(uiDrawPath *, double, double); void uiDrawPathNewFigure(uiDrawPath *, double, double);
// TODO uiDrawPathNewFigureWithArc
void uiDrawPathLineTo(uiDrawPath *, double, double); void uiDrawPathLineTo(uiDrawPath *, double, double);
// notes: angles are both relative to 0 and go counterclockwise // notes: angles are both relative to 0 and go counterclockwise
// TODO is the initial line segment on cairo and OS X a proper join? // TODO is the initial line segment on cairo and OS X a proper join?
void uiDrawPathArcTo(uiDrawPath *, double, double, double, double, double); void uiDrawPathArcTo(uiDrawPath *, double, double, double, double, double);
void uiDrawPathBezierTo(uiDrawPath *, double, double, double, double, double, double); void uiDrawPathBezierTo(uiDrawPath *, double, double, double, double, double, double);
// TODO quadratic bezier
void uiDrawPathCloseFigure(uiDrawPath *); void uiDrawPathCloseFigure(uiDrawPath *);
void uiDrawPathAddRectangle(uiDrawPath *, double, double, double, double); void uiDrawPathAddRectangle(uiDrawPath *, double, double, double, double);