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);
|
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)
|
void uiDrawCloseFigure(uiDrawContext *c)
|
||||||
{
|
{
|
||||||
cairo_close_path(c->cr);
|
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
|
// 4 september 2015
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <math.h>
|
||||||
#include "area.h"
|
#include "area.h"
|
||||||
|
|
||||||
// #qo pkg-config: gtk+-3.0
|
// #qo pkg-config: gtk+-3.0
|
||||||
|
@ -48,6 +50,31 @@ static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p)
|
||||||
sp.Thickness = 1;
|
sp.Thickness = 1;
|
||||||
sp.MiterLimit = uiDrawDefaultMiterLimit;
|
sp.MiterLimit = uiDrawDefaultMiterLimit;
|
||||||
uiDrawStroke(p->Context, &sp);
|
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)
|
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 uiDrawMoveTo(uiDrawContext *, intmax_t, intmax_t);
|
||||||
void uiDrawLineTo(uiDrawContext *, intmax_t, intmax_t);
|
void uiDrawLineTo(uiDrawContext *, intmax_t, intmax_t);
|
||||||
void uiDrawRectangle(uiDrawContext *, intmax_t, intmax_t, 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 uiDrawCloseFigure(uiDrawContext *);
|
||||||
|
|
||||||
void uiDrawStroke(uiDrawContext *, uiDrawStrokeParams *);
|
void uiDrawStroke(uiDrawContext *, uiDrawStrokeParams *);
|
||||||
|
@ -87,8 +89,8 @@ void uiDrawFill(uiDrawContext *, uiDrawFillMode);
|
||||||
// cairo gdi core graphics
|
// cairo gdi core graphics
|
||||||
// move_to MoveToEx MoveToPoint
|
// move_to MoveToEx MoveToPoint
|
||||||
// line_to LineTo AddLineToPoint
|
// line_to LineTo AddLineToPoint
|
||||||
// arc Arc/ArcTo/AngleArc/Ellipse AddArc/AddArcToPoint/AddEllipseInRect
|
// arc Arc/ArcTo/AngleArc/Pie AddArc/AddArcToPoint/AddEllipseInRect
|
||||||
// arc_negative Pie AddArc/AddArcToPoint
|
// arc_negative Arc/ArcTo/AngleArc/Pie AddArc/AddArcToPoint
|
||||||
// curve_to PolyBezier/PolyBezierTo AddCurveToPoint
|
// curve_to PolyBezier/PolyBezierTo AddCurveToPoint
|
||||||
// rectangle Rectangle AddRect
|
// rectangle Rectangle AddRect
|
||||||
// [arc functions?] Chord [arc functions?]
|
// [arc functions?] Chord [arc functions?]
|
||||||
|
@ -112,3 +114,26 @@ void uiDrawFill(uiDrawContext *, uiDrawFillMode);
|
||||||
// - arbitrary patterns
|
// - arbitrary patterns
|
||||||
// - solid colors, arbitrary spaces
|
// - solid colors, arbitrary spaces
|
||||||
// - shadows
|
// - 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