More drawing API work, including some Windows code so I don't forget important implementation details.
This commit is contained in:
parent
850f996d27
commit
cd215c260c
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
29
gtkarea/ui.h
29
gtkarea/ui.h
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue