From 01afb5846c2b9d7c58961d38b27cd597d367d766 Mon Sep 17 00:00:00 2001 From: Bill Kendrick Date: Sat, 1 Jun 2024 01:35:50 -0700 Subject: [PATCH] api->retract_undo() added to Magic API; used by Filled Polygon New API function which rolls back the Undo buffer (which is snapshotted upon a mousedown event ahead of calling the Magic tool's `_click()` function.) Dangerous; use sparingly! Filled Polygon uses this to prevent partially-created (aka unfinished aka incomplete) polygons -- the preview lines and control points -- from being recorded and wasting space in the Undo history, or reappearing upon Redo. TODO - Other tools (e.g., Clone) would certainly benefit from this. TODO - Needs more testing to help identify any bugs/issues introduced by this! TODO - Magic API docs need updating. This is probably a sufficient solution that will make https://sourceforge.net/p/tuxpaint/feature-requests/246/, '"Overlay" surface in Magic API', unnecessary. --- Makefile | 4 ++-- docs/CHANGES.txt | 8 +++++++- magic/src/polyfill.c | 34 +++++++++++++++++++++++++++++++--- src/tp_magic_api.h.in | 7 ++++++- src/tuxpaint.c | 30 +++++++++++++++++------------- 5 files changed, 63 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index ed849d7da..b537e5d72 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ # Various contributors (see AUTHORS.txt) # https://tuxpaint.org/ -# June 14, 2002 - February 29, 2024 +# June 14, 2002 - June 1, 2024 # The version number, for release: @@ -24,7 +24,7 @@ else VER_DATE=$(shell date "+%Y-%m-%d") endif -MAGIC_API_VERSION:=0x00000009 +MAGIC_API_VERSION:=0x0000000A # Need to know the OS SYSNAME:=$(shell uname -s) diff --git a/docs/CHANGES.txt b/docs/CHANGES.txt index 2f403abff..6b29f69a0 100644 --- a/docs/CHANGES.txt +++ b/docs/CHANGES.txt @@ -6,7 +6,7 @@ Copyright (c) 2002-2024 Various contributors (see below, and AUTHORS.txt) https://tuxpaint.org/ -2024.May.30 (0.9.33) +2024.June.1 (0.9.33) * New Magic Tools: ---------------- * Dither & Dither (Keep Color): Replaces all or part of a drawing @@ -42,6 +42,12 @@ https://tuxpaint.org/ + Idea from O'Hare The Rabbit + Coding by Bill Kendrick + * Ability for Magic tools to retract an undo buffer snapshot + (`api->retract_undo()`). + + Used by new Filled Polygon magic tool. + + Note: `TP_MAGIC_API_VERSION` bumped to 0x0000000A. + + Bill Kendrick + * Improvements to Eraser tool: ---------------------------- * Transparent erasers diff --git a/magic/src/polyfill.c b/magic/src/polyfill.c index 7877db791..edd2cee83 100644 --- a/magic/src/polyfill.c +++ b/magic/src/polyfill.c @@ -7,7 +7,7 @@ Scanline polygon fill routine based on public-domain code by Darel Rex Finley, 2007 - Last updated: May 30, 2024 + Last updated: June 1, 2024 */ @@ -19,6 +19,9 @@ #include "SDL_image.h" #include "SDL_mixer.h" +// #define DEBUG + + enum { TOOL_POLYFILL, @@ -222,7 +225,7 @@ polyfill_click(magic_api * api, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_U polyfill_dragged = 0; #ifdef DEBUG - printf("Click. num_pts = %d\n", polyfill_num_pts); + printf("\nClick. num_pts = %d\n", polyfill_num_pts); #endif /* See if we're clicking a pre-existing point, to edit it? */ @@ -242,6 +245,7 @@ polyfill_click(magic_api * api, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_U #endif polyfill_draw_preview(api, canvas, 1); + return; } @@ -407,7 +411,7 @@ polyfill_release(magic_api * api, int which ATTRIBUTE_UNUSED, } /* Moved (or placed) the final spot at the beginning? */ - if (polyfill_num_pts > 2 && + if (polyfill_num_pts > 3 && ((polyfill_editing == polyfill_num_pts - 1 && abs(x - polyfill_pt_x[0]) <= SNAP_SIZE && abs(y - polyfill_pt_y[0]) <= SNAP_SIZE) || @@ -442,6 +446,12 @@ polyfill_release(magic_api * api, int which ATTRIBUTE_UNUSED, /* Play "finish" sound effect */ api->playsound(snd_effects[SND_FINISH], 128 /* TODO could be clever and determine midpoint of polygon */, 255); + +#ifdef DEBUG + printf("Retract the undo we just took (ahead of finishing polygon)!\n"); +#endif + api->retract_undo(); + SDL_BlitSurface(canvas, NULL, snapshot, NULL); } else { @@ -493,6 +503,16 @@ polyfill_release(magic_api * api, int which ATTRIBUTE_UNUSED, update_rect->y = 0; update_rect->w = canvas->w; update_rect->h = canvas->h; + + /* Unless we just started a new polygon, don't let + Tux Paint take more undo snapshots */ + if (polyfill_num_pts > 1) + { +#ifdef DEBUG + printf("Retract the undo we just took!\n"); +#endif + api->retract_undo(); + } } void polyfill_set_color(magic_api * api, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, @@ -555,6 +575,14 @@ void polyfill_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNU void polyfill_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas) { + if (polyfill_num_pts > 0) + { +#ifdef DEBUG + printf("Retract the undo we just took (on our way out)!\n"); +#endif + api->retract_undo(); + } + polyfill_num_pts = 0; polyfill_editing = MAX_PTS; polyfill_active = 0; diff --git a/src/tp_magic_api.h.in b/src/tp_magic_api.h.in index 22c37ad07..b2c8b6c73 100644 --- a/src/tp_magic_api.h.in +++ b/src/tp_magic_api.h.in @@ -1,7 +1,7 @@ #ifndef TP_MAGIC_API_H #define TP_MAGIC_API_H -/* src/tp_magic_api.h.in last modified 2023-12-29 */ +/* src/tp_magic_api.h.in last modified 2024-06-01 */ #include "SDL.h" #include "SDL_mixer.h" @@ -161,6 +161,11 @@ typedef struct magic_api_t { clicked; useful for not applying the same effect from 'last' to 'canvas' more than once per click-and-drag sequence */ Uint8 (*touched)(int, int); + + /* Retracts the last undo buffer record; useful if a Magic tool has + drawn something "temporary" (such as guides) onto the canvas during + a previous click event. */ + void (*retract_undo)(void); } magic_api; diff --git a/src/tuxpaint.c b/src/tuxpaint.c index cf80768f7..7d13fc051 100644 --- a/src/tuxpaint.c +++ b/src/tuxpaint.c @@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA (See COPYING.txt) - June 14, 2002 - May 25, 2024 + June 14, 2002 - June 1, 2024 */ #include "platform.h" @@ -1573,6 +1573,7 @@ typedef struct magic_funcs_s void (*release)(magic_api *, int, SDL_Surface *, SDL_Surface *, int, int, SDL_Rect *); void (*switchin)(magic_api *, int, int, SDL_Surface *, SDL_Surface *); void (*switchout)(magic_api *, int, int, SDL_Surface *, SDL_Surface *); + void (*retract_undo)(void); } magic_funcs_t; @@ -2304,6 +2305,7 @@ static SDL_Surface *magic_scale(SDL_Surface * surf, int w, int h, int aspect); static SDL_Surface *magic_rotate_scale(SDL_Surface * surf, int r, int w); static void reset_touched(void); static Uint8 magic_touched(int x, int y); +static void magic_retract_undo(void); static void magic_switchin(SDL_Surface * last); static void magic_switchout(SDL_Surface * last); @@ -5442,18 +5444,7 @@ static void mainloop(void) /* Start doing magic! */ - /* These switchout/in are here for Magic tools that abuse the canvas - by drawing widgets on them; you don't want the widgets recorded as part - of the canvas in the undo buffer! - HOWEVER, as Pere noted in 2010.March, this causes many 'normal' Magic - tools to not work right, because they lose their record of the 'original' - canvas, before the user started using the tool (e.g., Rails, Perspective, Zoom). - FIXME: Some in-between solution is needed (a 'clean up the canvas'/'dirty the canvas' - pair of functions for the widgety abusers?) -bjk 2010.03.22 */ - - /* magic_switchout(canvas); *//* <-- FIXME: I dislike this -bjk 2009.10.13 */ rec_undo_buffer(); - /* magic_switchin(canvas); *//* <-- FIXME: I dislike this -bjk 2009.10.13 */ if (cur_undo > 0) undo_ctr = cur_undo - 1; @@ -21600,7 +21591,7 @@ static void load_magic_plugins(void) magic_api_struct->scale = magic_scale; magic_api_struct->rotate_scale = magic_rotate_scale; magic_api_struct->touched = magic_touched; - + magic_api_struct->retract_undo = magic_retract_undo; do { @@ -23775,6 +23766,19 @@ static Uint8 magic_touched(int x, int y) return (res); } +/** + * Removes the latest undo recorded + */ +void magic_retract_undo(void) { + if (cur_undo > 0) + cur_undo--; + else + cur_undo = NUM_UNDO_BUFS - 1; + + newest_undo = cur_undo; +} + + /** * Allow the user to select a color from one of the * pixels within their picture.