diff --git a/docs/CHANGES.txt b/docs/CHANGES.txt index 1d8383f96..144035ae4 100644 --- a/docs/CHANGES.txt +++ b/docs/CHANGES.txt @@ -38,6 +38,7 @@ https://tuxpaint.org/ + Kaleidoscope, Symmetric L/R & U/D, Pattern, Tiles + Blur + Bricks + + Clone + Confetti + Googly Eyes + Puzzle @@ -52,6 +53,9 @@ https://tuxpaint.org/ * String 'V' and String corner magic tools preview with XOR effect. Bill Kendrick + * Clone performance improved. + Bill Kendrick + * Other Improvements: ------------------- * Word-wrap long button labels, for better readability. diff --git a/magic/src/clone.c b/magic/src/clone.c index 0ff07d5e1..365c51c83 100644 --- a/magic/src/clone.c +++ b/magic/src/clone.c @@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA (See COPYING.txt) - Last updated: February 12, 2023 + Last updated: April 20, 2023 */ #include @@ -60,11 +60,12 @@ int clone_src_x, clone_src_y; int clone_drag_start_x, clone_drag_start_y; SDL_Surface *clone_last; int clone_crosshair_visible; +int clone_radius = 16; /* Local function prototype: */ -int clone_init(magic_api * api); +int clone_init(magic_api * api, Uint32 disabled_features); Uint32 clone_api_version(void); int clone_get_tool_count(magic_api * api); SDL_Surface *clone_get_icon(magic_api * api, int which); @@ -93,9 +94,12 @@ int clone_modes(magic_api * api, int which); void clone_crosshairs(magic_api * api, SDL_Surface * canvas, int x, int y); void done_cloning(magic_api * api, SDL_Surface * canvas, SDL_Rect * update_rect); +Uint8 clone_accepted_sizes(magic_api * api, int which, int mode); +Uint8 clone_default_size(magic_api * api, int which, int mode); +void clone_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * last, Uint8 size, SDL_Rect * update_rect); // No setup required: -int clone_init(magic_api * api) +int clone_init(magic_api * api, Uint32 disabled_features ATTRIBUTE_UNUSED) { char fname[1024]; @@ -167,28 +171,35 @@ static void do_clone(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last, int x, int y) { magic_api *api = (magic_api *) ptr; - Uint8 r, g, b; - int xx, yy; + int yy, dx; int srcx, srcy; - Uint32 pixel; + SDL_Rect src; + SDL_Rect dest; srcx = clone_src_x + (x - clone_drag_start_x); srcy = clone_src_y + (y - clone_drag_start_y); if (!api->touched(x, y)) { - for (yy = -16; yy < 16; yy++) + for (yy = -clone_radius; yy < clone_radius; yy++) { - for (xx = -16; xx < 16; xx++) - { - if (api->in_circle(xx, yy, 16)) - { - SDL_GetRGB(api->getpixel(last, srcx + xx, srcy + yy), last->format, - &r, &g, &b); - pixel = SDL_MapRGB(canvas->format, r, g, b); - api->putpixel(canvas, x + xx, y + yy, pixel); - } - } + /* Since we're just copying from last to canvas, + speed things up by using SDL_BlitSurface() on + slices, rather than getpixel()/putpixel() on + individual pixels (along with an in_circle() test) */ + dx = sqrt(pow(clone_radius, 2) - pow(yy, 2)); + + src.y = srcy + yy; + src.x = srcx - dx; + src.w = dx * 2; + src.h = 1; + + dest.y = y + yy; + dest.x = x - dx; + dest.w = dx * 2; + dest.h = 1; + + SDL_BlitSurface(last, &src, canvas, &dest); } } } @@ -201,6 +212,7 @@ void clone_drag(magic_api * api, int which, SDL_Surface * canvas, /* Step 3 - Actively cloning (moving the mouse) */ /* Erase crosshairs at old source position */ + //printf("clone_drag: erasing crosshairs (state = %d)\n", clone_state); clone_crosshairs(api, canvas, clone_src_x, clone_src_y); clone_crosshair_visible = 0; @@ -241,6 +253,7 @@ void clone_doit(magic_api * api, int which, SDL_Surface * canvas, if (crosshairs) { + //printf("clone_doit: drawing crosshairs\n"); clone_crosshairs(api, canvas, clone_src_x, clone_src_y); /* FIXME be more clever */ update_rect->x = 0; @@ -251,10 +264,10 @@ void clone_doit(magic_api * api, int which, SDL_Surface * canvas, } else { - update_rect->x = x - 64; - update_rect->y = y - 64; - update_rect->w = (ox + 128) - update_rect->x; - update_rect->h = (oy + 128) - update_rect->y; + update_rect->x = x - clone_radius * 4; + update_rect->y = y - clone_radius * 4; + update_rect->w = (ox + clone_radius * 8) - update_rect->x; + update_rect->h = (oy + clone_radius * 8) - update_rect->y; } api->playsound(clone_snd, (x * 255) / canvas->w, 255); @@ -276,6 +289,7 @@ void clone_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, SDL_BlitSurface(last, NULL, clone_last, NULL); /* Draw crosshairs at starting source position */ + //printf("clone_click: drawing crosshairs\n"); clone_crosshairs(api, canvas, clone_src_x, clone_src_y); clone_crosshair_visible = 1; update_rect->x = x - 15; @@ -315,6 +329,7 @@ void done_cloning(magic_api * api, SDL_Surface * canvas, /* Erase crosshairs from source position, now that we're all done */ if (clone_crosshair_visible) { + //printf("done_cloning: erasing crosshairs\n"); clone_crosshairs(api, canvas, clone_src_x, clone_src_y); update_rect->x = clone_src_x - 15; update_rect->y = clone_src_y - 15; @@ -385,3 +400,17 @@ int clone_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { return (MODE_PAINT); } + + +Uint8 clone_accepted_sizes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) { + return 8; +} + +Uint8 clone_default_size(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) { + return 2; +} + +void clone_set_size(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, Uint8 size, SDL_Rect * update_rect ATTRIBUTE_UNUSED) +{ + clone_radius = size * 8; +} diff --git a/src/tuxpaint.c b/src/tuxpaint.c index c90dfe9e5..e8b970248 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 - April 19, 2023 + June 14, 2002 - April 20, 2023 */ #include "platform.h" @@ -27354,6 +27354,8 @@ static void magic_switchout(SDL_Surface * last) draw_toolbar(); update_screen_rect(&r_tools); } + + update_screen_rect(&r_canvas); } }