diff --git a/gtkarea/area.c b/gtkarea/area.c index ccf1e47a..0ff06ff9 100644 --- a/gtkarea/area.c +++ b/gtkarea/area.c @@ -1,10 +1,6 @@ // 4 september 2015 #include "area.h" -struct uiDrawContext { - cairo_t *cr; -}; - struct areaPrivate { uiArea *a; uiAreaHandler *ah; @@ -125,10 +121,8 @@ static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr) struct areaPrivate *ap = a->priv; uiAreaDrawParams dp; double clipX0, clipY0, clipX1, clipY1; - uiDrawContext ctxt; - ctxt.cr = cr; - dp.Context = &ctxt; + dp.Context = newContext(cr); dp.ClientWidth = ap->clientWidth; dp.ClientHeight = ap->clientHeight; @@ -152,6 +146,7 @@ static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr) (*(ap->ah->Draw))(ap->ah, ap->a, &dp); + g_free(dp.Context); return FALSE; } diff --git a/gtkarea/area.h b/gtkarea/area.h index 9c625fbb..fff3aabf 100644 --- a/gtkarea/area.h +++ b/gtkarea/area.h @@ -31,3 +31,5 @@ extern GType areaWidget_get_type(void); extern GtkWidget *newArea(uiAreaHandler *ah); extern void areaUpdateScroll(GtkWidget *area); + +extern uiDrawContext *newContext(cairo_t *); diff --git a/gtkarea/draw.c b/gtkarea/draw.c new file mode 100644 index 00000000..8a516971 --- /dev/null +++ b/gtkarea/draw.c @@ -0,0 +1,75 @@ +// 6 september 2015 +#include "area.h" + +struct uiDrawContext { + cairo_t *cr; + gboolean hasPath; +}; + +uiDrawContext *newContext(cairo_t *cr) +{ + uiDrawContext *c; + + c = (uiDrawContext *) g_malloc0(sizeof (uiDrawContext)); + c->cr = cr; + c->hasPath = FALSE; + return c; +} + +static void prepPath(uiDrawContext *c) +{ + if (c->hasPath) + return; + cairo_new_path(c->cr); + c->hasPath = TRUE; +} + +void uiDrawMoveTo(uiDrawContext *c, intmax_t x, intmax_t y) +{ + prepPath(c); + cairo_move_to(c->cr, (double) x + 0.5, (double) y + 0.5); +} + +void uiDrawLineTo(uiDrawContext *c, intmax_t x, intmax_t y) +{ + prepPath(c); + cairo_line_to(c->cr, (double) x + 0.5, (double) y + 0.5); +} + +#define R(c) (((c) >> 16) & 0xFF) +#define G(c) (((c) >> 8) & 0xFF) +#define B(c) ((c) & 0xFF) + +void uiDrawStroke(uiDrawContext *c, uiDrawStrokeParams *p) +{ + cairo_set_source_rgb(c->cr, + ((double) R(p->RGB)) / 255, + ((double) G(p->RGB)) / 255, + ((double) B(p->RGB)) / 255); + switch (p->Cap) { + case uiDrawLineCapFlat: + cairo_set_line_cap(c->cr, CAIRO_LINE_CAP_BUTT); + break; + case uiDrawLineCapRound: + cairo_set_line_cap(c->cr, CAIRO_LINE_CAP_ROUND); + break; + case uiDrawLineCapSquare: + cairo_set_line_cap(c->cr, CAIRO_LINE_CAP_SQUARE); + break; + } + switch (p->Join) { + case uiDrawLineJoinMiter: + cairo_set_line_join(c->cr, CAIRO_LINE_JOIN_MITER); + cairo_set_miter_limit(c->cr, p->MiterLimit); + break; + case uiDrawLineJoinRound: + cairo_set_line_join(c->cr, CAIRO_LINE_JOIN_ROUND); + break; + case uiDrawLineJoinBevel: + cairo_set_line_join(c->cr, CAIRO_LINE_JOIN_BEVEL); + break; + } + cairo_set_line_width(c->cr, p->Thickness); + cairo_stroke(c->cr); + c->hasPath = FALSE; +} diff --git a/gtkarea/main.c b/gtkarea/main.c index 859905fb..3e8fd57a 100644 --- a/gtkarea/main.c +++ b/gtkarea/main.c @@ -12,9 +12,27 @@ static struct handler h; static GtkWidget *nhspinb; static GtkWidget *nvspinb; -static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *params) +static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p) { - // TODO + uiDrawStrokeParams sp; + + uiDrawMoveTo(p->Context, p->ClipX + 5, p->ClipY + 5); + uiDrawLineTo(p->Context, (p->ClipX + p->ClipWidth) - 5, (p->ClipY + p->ClipHeight) - 5); + sp.RGB = 0xFF0000; + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.Thickness = 1; + sp.MiterLimit = 10; + uiDrawStroke(p->Context, &sp); + + uiDrawMoveTo(p->Context, p->ClipX, p->ClipY); + uiDrawLineTo(p->Context, p->ClipX + p->ClipWidth, p->ClipY); + sp.RGB = 0x000080; + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.Thickness = 1; + sp.MiterLimit = 10; + uiDrawStroke(p->Context, &sp); } static uintmax_t handlerHScrollMax(uiAreaHandler *a, uiArea *area) diff --git a/gtkarea/ui.h b/gtkarea/ui.h index 2d7c15e6..c6e3c93d 100644 --- a/gtkarea/ui.h +++ b/gtkarea/ui.h @@ -29,3 +29,40 @@ struct uiAreaDrawParams { intmax_t HScrollPos; intmax_t VScrollPos; }; + +// TODO default miter limit? +// cairo - 10.0 +// GDI - ? +// Core Graphics - ? + +// TODO dotting/dashing + +typedef struct uiDrawStrokeParams uiDrawStrokeParams; +typedef enum uiDrawLineCap uiDrawLineCap; +typedef enum uiDrawLineJoin uiDrawLineJoin; + +typedef uint32_t uiRGB; + +enum uiDrawLineCap { + uiDrawLineCapFlat, + uiDrawLineCapRound, + uiDrawLineCapSquare, +}; + +enum uiDrawLineJoin { + uiDrawLineJoinMiter, + uiDrawLineJoinRound, + uiDrawLineJoinBevel, +}; + +struct uiDrawStrokeParams { + uiRGB RGB; + uiDrawLineCap Cap; + uiDrawLineJoin Join; + intmax_t Thickness; + intmax_t MiterLimit; +}; + +void uiDrawMoveTo(uiDrawContext *, intmax_t, intmax_t); +void uiDrawLineTo(uiDrawContext *, intmax_t, intmax_t); +void uiDrawStroke(uiDrawContext *, uiDrawStrokeParams *);