More drawing API work, including some Windows code so I don't forget important implementation details.

This commit is contained in:
Pietro Gagliardi 2015-09-07 15:34:14 -04:00
parent 850f996d27
commit cd215c260c
4 changed files with 188 additions and 2 deletions

View File

@ -48,6 +48,20 @@ void uiDrawRectangle(uiDrawContext *c, intmax_t x, intmax_t y, intmax_t width, i
cairo_rectangle(c->cr, (double) x + 0.5, (double) y + 0.5, width, height);
}
void uiDrawArc(uiDrawContext *c, intmax_t xCenter, intmax_t yCenter, intmax_t radius, double startAngle, double endAngle, int lineFromCurrentPointToStart)
{
if (!lineFromCurrentPointToStart)
cairo_new_sub_path(c->cr);
// the Windows AngleArc() function only goes counterclockwise, so our uiDrawArc() function does too
// simulate it in cairo by drawing a negative arc from end to start
cairo_arc_negative(c->cr,
((double) xCenter) + 0.5,
((double) yCenter) + 0.5,
radius,
endAngle,
startAngle);
}
void uiDrawCloseFigure(uiDrawContext *c)
{
cairo_close_path(c->cr);

120
gtkarea/draw_windows.c Normal file
View File

@ -0,0 +1,120 @@
// 7 september 2015
#include "area.h"
struct uiDrawContext {
HDC mainDC;
// when drawing in RGBA mode, we need to use this
HDC alphaDC;
HBITMAP alphaBitmap;
// and this is the DC we actually draw to, either mainDC or alphaDC
HDC currentDC;
// source color
BOOL useRGB;
BOOL useAlpha;
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t a;
};
uiDrawContext *newContext(HDC dc)
{
uiDrawContext *c;
c = (uiDrawContext *) g_malloc0(sizeof (uiDrawContext));
c->mainDC = dc;
return c;
}
void uiDrawBeginPathRGB(uiDrawContext *c, uint8_t r, uint8_t g, uint8_t b)
{
c->useRGB = TRUE;
c->useAlpha = FALSE;
c->r = r;
c->g = g;
c->b = b;
c->currentDC = c->mainDC;
if (BeginPath(c->currentDC) == 0)
logLastError("error beginning new path in uiDrawBeginPathRGB()");
}
void uiDrawBeginPathRGBA(uiDrawContext *c, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
// TODO
}
void uiDrawMoveTo(uiDrawContext *c, intmax_t x, intmax_t y)
{
if (MoveToEx(c->currentDC, x, y, NULL) == 0)
logLastError("error moving to point in uiDrawMoveTo()");
}
void uiDrawLineTo(uiDrawContext *c, intmax_t x, intmax_t y)
{
if (LineTo(c->currentDC, x, y) == 0)
logLastError("error drawing line in uiDrawLineTo()");
}
void uiDrawRectangle(uiDrawContext *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height)
{
if (Rectangle(c->currentDC, x, y, x + width, y + height) == 0)
logLastError("error drawing rectangle in uiDrawRectangle()");
}
void uiDrawArc(uiDrawContext *c, intmax_t xCenter, intmax_t yCenter, intmax_t radius, double startAngle, double endAngle, int lineFromCurrentPointToStart)
{
if (!lineFromCurrentPointToStart) {
// TODO
}
// TODO convert radians to degrees
if (AngleArc(c->currentDC,
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 uiDrawCloseFigure(uiDrawContext *c)
{
if (CloseFigure(c->currentDC) == 0)
logLastError("error closing figure in uiDrawCloseFigure()");
}
void uiDrawStroke(uiDrawContext *c, uiDrawStrokeParams *p)
{
// TODO
switch (p->Cap) {
case uiDrawLineCapFlat:
break;
case uiDrawLineCapRound:
break;
case uiDrawLineCapSquare:
break;
}
switch (p->Join) {
case uiDrawLineJoinMiter:
break;
case uiDrawLineJoinRound:
break;
case uiDrawLineJoinBevel:
break;
}
}
void uiDrawFill(uiDrawContext *c, uiDrawFillMode mode)
{
// TODO
switch (mode) {
case uiDrawFillModeWinding:
break;
case uiDrawFillModeAlternate:
break;
}
}

View File

@ -1,4 +1,6 @@
// 4 september 2015
#define _GNU_SOURCE
#include <math.h>
#include "area.h"
// #qo pkg-config: gtk+-3.0
@ -48,6 +50,31 @@ static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p)
sp.Thickness = 1;
sp.MiterLimit = uiDrawDefaultMiterLimit;
uiDrawStroke(p->Context, &sp);
uiDrawBeginPathRGB(p->Context, 0x80, 0xC0, 0x00);
uiDrawMoveTo(p->Context, 400, 100);
uiDrawArc(p->Context,
400, 100,
50,
30. * (M_PI / 180.),
// note the end angle here
// in GDI, the second angle to AngleArc() is relative to the start, not to 0
330. * (M_PI / 180.),
1);
// TODO add a checkbox for this
uiDrawLineTo(p->Context, 400, 100);
uiDrawArc(p->Context,
510, 100,
50,
30. * (M_PI / 180.),
330. * (M_PI / 180.),
0);
uiDrawCloseFigure(p->Context);
sp.Cap = uiDrawLineCapFlat;
sp.Join = uiDrawLineJoinMiter;
sp.Thickness = 1;
sp.MiterLimit = uiDrawDefaultMiterLimit;
uiDrawStroke(p->Context, &sp);
}
static uintmax_t handlerHScrollMax(uiAreaHandler *a, uiArea *area)

View File

@ -78,6 +78,8 @@ void uiDrawBeginPathRGBA(uiDrawContext *, uint8_t, uint8_t, uint8_t, uint8_t);
void uiDrawMoveTo(uiDrawContext *, intmax_t, intmax_t);
void uiDrawLineTo(uiDrawContext *, intmax_t, intmax_t);
void uiDrawRectangle(uiDrawContext *, intmax_t, intmax_t, intmax_t, intmax_t);
// notes: angles are both relative to 0 and go counterclockwise
void uiDrawArc(uiDrawContext *, intmax_t, intmax_t, intmax_t, double, double, int);
void uiDrawCloseFigure(uiDrawContext *);
void uiDrawStroke(uiDrawContext *, uiDrawStrokeParams *);
@ -87,8 +89,8 @@ void uiDrawFill(uiDrawContext *, uiDrawFillMode);
// cairo gdi core graphics
// move_to MoveToEx MoveToPoint
// line_to LineTo AddLineToPoint
// arc Arc/ArcTo/AngleArc/Ellipse AddArc/AddArcToPoint/AddEllipseInRect
// arc_negative Pie AddArc/AddArcToPoint
// arc Arc/ArcTo/AngleArc/Pie AddArc/AddArcToPoint/AddEllipseInRect
// arc_negative Arc/ArcTo/AngleArc/Pie AddArc/AddArcToPoint
// curve_to PolyBezier/PolyBezierTo AddCurveToPoint
// rectangle Rectangle AddRect
// [arc functions?] Chord [arc functions?]
@ -112,3 +114,26 @@ void uiDrawFill(uiDrawContext *, uiDrawFillMode);
// - arbitrary patterns
// - solid colors, arbitrary spaces
// - shadows
// arcs
// cairo_arc/arc_negative
// - parameters: center, radius, angle1 radians, angle2 radins
// - if angle2 < angle1, TODO
// - if angle2 > angle1, TODO
// - line segment from current point to beginning of arc
// - arc: clockwise, arc_negative: counterclockwise
// - circular
// GDI Arc/Pie
// - parameters: bounding box, start point, end point
// - current position not used/changed
// - either clockwise or counterclockwise
// - elliptical
// GDI ArcTo
// - same as Arc except line segment from current point to beginning of arc
// - there does not appear to be a PieTo
// GDI AngleArc
// - parameters: center, radius, angle1 degrees, angle2 degrees
// - line segment from current position to beginning of arc
// - counterclockwise
// - circular
// - can be used to draw pies too; MSDN example demonstrates