Clone: Support sizes; performance boost

This commit is contained in:
Bill Kendrick 2023-04-20 22:15:01 -07:00
parent b739f7dccb
commit 06a36c571e
3 changed files with 57 additions and 22 deletions

View file

@ -38,6 +38,7 @@ https://tuxpaint.org/
+ Kaleidoscope, Symmetric L/R & U/D, Pattern, Tiles + Kaleidoscope, Symmetric L/R & U/D, Pattern, Tiles
+ Blur + Blur
+ Bricks + Bricks
+ Clone
+ Confetti + Confetti
+ Googly Eyes + Googly Eyes
+ Puzzle + Puzzle
@ -52,6 +53,9 @@ https://tuxpaint.org/
* String 'V' and String corner magic tools preview with XOR effect. * String 'V' and String corner magic tools preview with XOR effect.
Bill Kendrick <bill@newbreedsoftware.com> Bill Kendrick <bill@newbreedsoftware.com>
* Clone performance improved.
Bill Kendrick <bill@newbreedsoftware.com>
* Other Improvements: * Other Improvements:
------------------- -------------------
* Word-wrap long button labels, for better readability. * Word-wrap long button labels, for better readability.

View file

@ -23,7 +23,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
(See COPYING.txt) (See COPYING.txt)
Last updated: February 12, 2023 Last updated: April 20, 2023
*/ */
#include <stdio.h> #include <stdio.h>
@ -60,11 +60,12 @@ int clone_src_x, clone_src_y;
int clone_drag_start_x, clone_drag_start_y; int clone_drag_start_x, clone_drag_start_y;
SDL_Surface *clone_last; SDL_Surface *clone_last;
int clone_crosshair_visible; int clone_crosshair_visible;
int clone_radius = 16;
/* Local function prototype: */ /* Local function prototype: */
int clone_init(magic_api * api); int clone_init(magic_api * api, Uint32 disabled_features);
Uint32 clone_api_version(void); Uint32 clone_api_version(void);
int clone_get_tool_count(magic_api * api); int clone_get_tool_count(magic_api * api);
SDL_Surface *clone_get_icon(magic_api * api, int which); 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 clone_crosshairs(magic_api * api, SDL_Surface * canvas, int x, int y);
void done_cloning(magic_api * api, SDL_Surface * canvas, void done_cloning(magic_api * api, SDL_Surface * canvas,
SDL_Rect * update_rect); 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: // No setup required:
int clone_init(magic_api * api) int clone_init(magic_api * api, Uint32 disabled_features ATTRIBUTE_UNUSED)
{ {
char fname[1024]; 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) SDL_Surface * canvas, SDL_Surface * last, int x, int y)
{ {
magic_api *api = (magic_api *) ptr; magic_api *api = (magic_api *) ptr;
Uint8 r, g, b; int yy, dx;
int xx, yy;
int srcx, srcy; int srcx, srcy;
Uint32 pixel; SDL_Rect src;
SDL_Rect dest;
srcx = clone_src_x + (x - clone_drag_start_x); srcx = clone_src_x + (x - clone_drag_start_x);
srcy = clone_src_y + (y - clone_drag_start_y); srcy = clone_src_y + (y - clone_drag_start_y);
if (!api->touched(x, 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++) /* Since we're just copying from last to canvas,
{ speed things up by using SDL_BlitSurface() on
if (api->in_circle(xx, yy, 16)) slices, rather than getpixel()/putpixel() on
{ individual pixels (along with an in_circle() test) */
SDL_GetRGB(api->getpixel(last, srcx + xx, srcy + yy), last->format, dx = sqrt(pow(clone_radius, 2) - pow(yy, 2));
&r, &g, &b);
pixel = SDL_MapRGB(canvas->format, r, g, b); src.y = srcy + yy;
api->putpixel(canvas, x + xx, y + yy, pixel); 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) */ /* Step 3 - Actively cloning (moving the mouse) */
/* Erase crosshairs at old source position */ /* 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_crosshairs(api, canvas, clone_src_x, clone_src_y);
clone_crosshair_visible = 0; clone_crosshair_visible = 0;
@ -241,6 +253,7 @@ void clone_doit(magic_api * api, int which, SDL_Surface * canvas,
if (crosshairs) if (crosshairs)
{ {
//printf("clone_doit: drawing crosshairs\n");
clone_crosshairs(api, canvas, clone_src_x, clone_src_y); clone_crosshairs(api, canvas, clone_src_x, clone_src_y);
/* FIXME be more clever */ /* FIXME be more clever */
update_rect->x = 0; update_rect->x = 0;
@ -251,10 +264,10 @@ void clone_doit(magic_api * api, int which, SDL_Surface * canvas,
} }
else else
{ {
update_rect->x = x - 64; update_rect->x = x - clone_radius * 4;
update_rect->y = y - 64; update_rect->y = y - clone_radius * 4;
update_rect->w = (ox + 128) - update_rect->x; update_rect->w = (ox + clone_radius * 8) - update_rect->x;
update_rect->h = (oy + 128) - update_rect->y; update_rect->h = (oy + clone_radius * 8) - update_rect->y;
} }
api->playsound(clone_snd, (x * 255) / canvas->w, 255); 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); SDL_BlitSurface(last, NULL, clone_last, NULL);
/* Draw crosshairs at starting source position */ /* Draw crosshairs at starting source position */
//printf("clone_click: drawing crosshairs\n");
clone_crosshairs(api, canvas, clone_src_x, clone_src_y); clone_crosshairs(api, canvas, clone_src_x, clone_src_y);
clone_crosshair_visible = 1; clone_crosshair_visible = 1;
update_rect->x = x - 15; 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 */ /* Erase crosshairs from source position, now that we're all done */
if (clone_crosshair_visible) if (clone_crosshair_visible)
{ {
//printf("done_cloning: erasing crosshairs\n");
clone_crosshairs(api, canvas, clone_src_x, clone_src_y); clone_crosshairs(api, canvas, clone_src_x, clone_src_y);
update_rect->x = clone_src_x - 15; update_rect->x = clone_src_x - 15;
update_rect->y = clone_src_y - 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); 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;
}

View file

@ -22,7 +22,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
(See COPYING.txt) (See COPYING.txt)
June 14, 2002 - April 19, 2023 June 14, 2002 - April 20, 2023
*/ */
#include "platform.h" #include "platform.h"
@ -27354,6 +27354,8 @@ static void magic_switchout(SDL_Surface * last)
draw_toolbar(); draw_toolbar();
update_screen_rect(&r_tools); update_screen_rect(&r_tools);
} }
update_screen_rect(&r_canvas);
} }
} }