Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New "smooth" and "orthogonal" drawing tools #198

Merged
merged 11 commits into from
Mar 22, 2024
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ set(sources
src/config.h
src/drawing.c
src/drawing.h
src/coordlist_ops.c
src/coordlist_ops.h
src/main.c
src/main.h
src/input.c
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,24 @@ A `RECT`-tool draws rectangles.

"red Rectangle" = RECT (color = "red");

A `SMOOTH`-tool that behaves like `PEN` except that it produces smoothed curves.
The degree of smoothing can be specified using `simplify=N`. `N` can
be imagined as approximate pixel range around the resulting line
within which intermediate points are "simplified away". Closed paths
can be drawn using the `snap=N` option where `N` indicates the maximum
distance between start and end point within which these "snap" together.

"smoothed line" = SMOOTH (color = "red" simplify=10 snap=30);

A `ORTHOGONAL`-tool that behaves like `SMOOTH` except that it produces
straight line segments that automatically snap to perfectly horizontal
and vertical direction when their direction deviated by a maximum of
`maxangle` degrees. Transitions between straight segments are drawn as
arcs with a certain `radius`, if these segments exceed a length of
`minlen`.

"ortho line" = ORTHOGONAL (color="red" size=5 simplify=15 radius=20 minlen=50 snap=40);

If you define a tool with the same name as an input-device
(see the output of `xinput --list`) this input-device uses this tool:

Expand Down
57 changes: 43 additions & 14 deletions src/callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#include "config.h"
#include "drawing.h"
#include "build-config.h"

#include "coordlist_ops.h"

gboolean on_expose (GtkWidget *widget,
cairo_t* cr,
Expand Down Expand Up @@ -142,10 +142,10 @@ void on_monitors_changed ( GdkScreen *screen,
parse_config(data); // also calls paint_context_new() :-(


data->default_pen = paint_context_new (data, GROMIT_PEN, data->red, 7,
0, GROMIT_ARROW_END, 1, G_MAXUINT);
data->default_eraser = paint_context_new (data, GROMIT_ERASER, data->red, 75,
0, GROMIT_ARROW_END, 1, G_MAXUINT);
data->default_pen = paint_context_new (data, GROMIT_PEN, data->red, 7, 0, GROMIT_ARROW_END,
5, 10, 15, 25, 1, 0, G_MAXUINT);
data->default_eraser = paint_context_new (data, GROMIT_ERASER, data->red, 75, 0, GROMIT_ARROW_END,
5, 10, 15, 25, 1, 0, G_MAXUINT);

if(!data->composited) // set shape
{
Expand Down Expand Up @@ -281,7 +281,7 @@ gboolean on_buttonpress (GtkWidget *win,
GromitPaintType type = devdata->cur_context->type;

// store original state to have dynamic update of line and rect
if (type == GROMIT_LINE || type == GROMIT_RECT)
if (type == GROMIT_LINE || type == GROMIT_RECT || type == GROMIT_SMOOTH || type == GROMIT_ORTHOGONAL)
{
copy_surface(data->aux_backbuffer, data->backbuffer);
}
Expand Down Expand Up @@ -398,6 +398,7 @@ gboolean on_motion (GtkWidget *win,
}
if (type == GROMIT_LINE)
{
GromitArrowType atype = devdata->cur_context->arrow_type;
draw_line (data, ev->device, devdata->lastx, devdata->lasty, ev->x, ev->y);
if (devdata->cur_context->arrowsize > 0)
{
Expand Down Expand Up @@ -444,12 +445,12 @@ gboolean on_buttonrelease (GtkWidget *win,
GromitData *data = (GromitData *) user_data;
/* get the device data for this event */
GromitDeviceData *devdata = g_hash_table_lookup(data->devdatatable, ev->device);
GromitPaintContext *ctx = devdata->cur_context;

gfloat direction = 0;
gint width = 0;
if(devdata->cur_context)
width = devdata->cur_context->arrowsize * devdata->cur_context->width / 2;

if(ctx)
width = ctx->arrowsize * ctx->width / 2;

if ((ev->x != devdata->lastx) ||
(ev->y != devdata->lasty))
Expand All @@ -458,11 +459,39 @@ gboolean on_buttonrelease (GtkWidget *win,
if (!devdata->is_grabbed)
return FALSE;

GromitPaintType type = devdata->cur_context->type;
GromitPaintType type = ctx->type;

if (type == GROMIT_SMOOTH || type == GROMIT_ORTHOGONAL)
{
gboolean joined = FALSE;
douglas_peucker(devdata->coordlist, ctx->simplify);
if (ctx->snapdist > 0)
joined = snap_ends(devdata->coordlist, ctx->snapdist);
if (type == GROMIT_SMOOTH) {
add_points(devdata->coordlist, 200);
devdata->coordlist = catmull_rom(devdata->coordlist, 5, joined);
} else {
orthogonalize(devdata->coordlist, ctx->maxangle, ctx->minlen);
round_corners(devdata->coordlist, ctx->radius, 6, joined);
}

copy_surface(data->backbuffer, data->aux_backbuffer);
GdkRectangle rect = {0, 0, data->width, data->height};
gdk_window_invalidate_rect(gtk_widget_get_window(data->win), &rect, 0);

GList *ptr = devdata->coordlist;
while (ptr && ptr->next)
{
GromitStrokeCoordinate *c1 = ptr->data;
GromitStrokeCoordinate *c2 = ptr->next->data;
ptr = ptr->next;
draw_line (data, ev->device, c1->x, c1->y, c2->x, c2->y);
}
}

if (devdata->cur_context->arrowsize != 0)
if (ctx->arrowsize != 0)
{
GromitArrowType atype = devdata->cur_context->arrow_type;
GromitArrowType atype = ctx->arrow_type;
if (type == GROMIT_LINE)
{
direction = atan2 (ev->y - devdata->lasty, ev->x - devdata->lastx);
Expand Down Expand Up @@ -615,8 +644,8 @@ void on_mainapp_selection_received (GtkWidget *widget,
"Keeping default.\n");
}
GromitPaintContext* line_ctx =
paint_context_new(data, GROMIT_PEN, fg_color, thickness,
0, GROMIT_ARROW_END, thickness, thickness);
paint_context_new(data, GROMIT_PEN, fg_color, thickness, 0, GROMIT_ARROW_END,
5, 10, 15, 25, 0, thickness, thickness);

GdkRectangle rect;
rect.x = MIN (startX,endX) - thickness / 2;
Expand Down
Loading
Loading