From 1cb04f1e0a13c844e3aa1ddd5b66bb738974a32d Mon Sep 17 00:00:00 2001 From: Bill Kendrick Date: Sun, 10 Jan 2021 22:46:34 -0800 Subject: [PATCH] "Clone" magic tool --- docs/CHANGES.txt | 6 +- magic/magic-docs/en/bricks.txt | 2 + magic/magic-docs/en/clone.txt | 7 + magic/magic-docs/en/html/bricks.html | 1 + magic/magic-docs/en/html/clone.html | 9 + magic/magic-docs/en/html/index.html | 3 +- magic/magic-docs/en/html/pixels.html | 5 +- magic/magic-docs/en/index.txt | 3 +- magic/magic-docs/en/pixels.txt | 6 +- magic/magic-docs/src/magic-docs.php | 18 +- magic/src/clone.c | 256 +++++++++++++++++++++++++++ 11 files changed, 304 insertions(+), 12 deletions(-) create mode 100644 magic/magic-docs/en/clone.txt create mode 100644 magic/magic-docs/en/html/clone.html create mode 100644 magic/src/clone.c diff --git a/docs/CHANGES.txt b/docs/CHANGES.txt index ec5f35b26..11f5c5208 100644 --- a/docs/CHANGES.txt +++ b/docs/CHANGES.txt @@ -8,10 +8,14 @@ http://www.tuxpaint.org/ $Id$ -2021.January.9 (0.9.26) +2021.January.10 (0.9.26) * New Magic Tools: ---------------- * Pixels + Draws large squares, for classic computer 'pixel art' style drawings. + + * Clone + Clones (copies, via painting) part of a drawing to another position. * Documentation updates --------------------- diff --git a/magic/magic-docs/en/bricks.txt b/magic/magic-docs/en/bricks.txt index fee9ab2e8..1cae79a83 100644 --- a/magic/magic-docs/en/bricks.txt +++ b/magic/magic-docs/en/bricks.txt @@ -5,3 +5,5 @@ These two tools intelligently paint large and small brick patterns on the canvas. The bricks can be tinted various redish hues by selecting different colors in the color palette. + + See also: Pixels diff --git a/magic/magic-docs/en/clone.txt b/magic/magic-docs/en/clone.txt new file mode 100644 index 000000000..8913e645f --- /dev/null +++ b/magic/magic-docs/en/clone.txt @@ -0,0 +1,7 @@ + Tux Paint "Magic" Tool: Clone + + By Bill Kendrick + + Clone (copy, via painting) part of the picture. Click ones to choose the + source, then click and drag to clone it elsewhere in the drawing. Once you + release, click to choose another source and start again. diff --git a/magic/magic-docs/en/html/bricks.html b/magic/magic-docs/en/html/bricks.html index e19341584..8f68ffa26 100644 --- a/magic/magic-docs/en/html/bricks.html +++ b/magic/magic-docs/en/html/bricks.html @@ -6,4 +6,5 @@

Tux Paint "Magic" Tool: Bricks

By Albert Cahalan <albert@users.sf.net>

These two tools intelligently paint large and small brick patterns on the canvas. The bricks can be tinted various redish hues by selecting different colors in the color palette.

+

See also: Pixels

\ No newline at end of file diff --git a/magic/magic-docs/en/html/clone.html b/magic/magic-docs/en/html/clone.html new file mode 100644 index 000000000..a18f3fe4e --- /dev/null +++ b/magic/magic-docs/en/html/clone.html @@ -0,0 +1,9 @@ + +Tux Paint "Magic" Tool: Clone + + + +

Tux Paint "Magic" Tool: Clone

+

By Bill Kendrick <bill@newbreedsoftware.com>

+

Clone (copy, via painting) part of the picture. Click ones to choose the source, then click and drag to clone it elsewhere in the drawing. Once you release, click to choose another source and start again.

+ \ No newline at end of file diff --git a/magic/magic-docs/en/html/index.html b/magic/magic-docs/en/html/index.html index dee3ad42e..08ea33072 100644 --- a/magic/magic-docs/en/html/index.html +++ b/magic/magic-docs/en/html/index.html @@ -11,6 +11,7 @@
  • Calligraphy
  • Cartoon
  • Chalk
  • +
  • Clone
  • Color and White
  • Color Shift
  • Confetti
  • @@ -19,7 +20,6 @@
  • Drip
  • Edges
  • Emboss
  • -
  • Fill
  • Fisheye
  • Flip
  • Flower
  • @@ -41,6 +41,7 @@
  • Pattern
  • Perspective
  • Picasso
  • +
  • Pixels
  • Puzzle
  • Rails
  • Rain
  • diff --git a/magic/magic-docs/en/html/pixels.html b/magic/magic-docs/en/html/pixels.html index 98c66c03b..d9a9ab7e5 100644 --- a/magic/magic-docs/en/html/pixels.html +++ b/magic/magic-docs/en/html/pixels.html @@ -5,5 +5,6 @@

    Tux Paint "Magic" Tool: Pixels

    By Bill Kendrick <bill@newbreedsoftware.com>

    -

    This tool draws squares on the canvas in a grid, simulating large pixels seen on older computer displays, and allowing simple "pixel art" to be created in Tux Paint.

    - +

    Draw large square "pixels" on the canvas.

    +

    See also: Bricks

    + \ No newline at end of file diff --git a/magic/magic-docs/en/index.txt b/magic/magic-docs/en/index.txt index a4f6712ca..0d017e19c 100644 --- a/magic/magic-docs/en/index.txt +++ b/magic/magic-docs/en/index.txt @@ -7,6 +7,7 @@ * Calligraphy * Cartoon * Chalk + * Clone * Color and White * Color Shift * Confetti @@ -15,7 +16,6 @@ * Drip * Edges * Emboss - * Fill * Fisheye * Flip * Flower @@ -37,6 +37,7 @@ * Pattern * Perspective * Picasso + * Pixels * Puzzle * Rails * Rain diff --git a/magic/magic-docs/en/pixels.txt b/magic/magic-docs/en/pixels.txt index 200c78812..cd00a5ec0 100644 --- a/magic/magic-docs/en/pixels.txt +++ b/magic/magic-docs/en/pixels.txt @@ -2,6 +2,6 @@ By Bill Kendrick - This tool draws squares on the canvas in a grid, simulating large pixels - seen on older computer displays, and allowing simple "pixel art" to be - created in Tux Paint. + Draw large square "pixels" on the canvas. + + See also: Bricks diff --git a/magic/magic-docs/src/magic-docs.php b/magic/magic-docs/src/magic-docs.php index 00c9a7991..ec6b237f3 100644 --- a/magic/magic-docs/src/magic-docs.php +++ b/magic/magic-docs/src/magic-docs.php @@ -5,7 +5,7 @@ individual HTML files for each of them, and an index.html that links to them all. */ /* Bill Kendrick */ -/* Oct. 8, 2009 - September 12, 2019 */ +/* Oct. 8, 2009 - January 10, 2020 */ /* Authors of the Magic tools: */ @@ -65,7 +65,8 @@ $tools = array( array('name'=>'Bricks', 'desc'=>'These two tools intelligently paint large and small brick patterns on the canvas. The bricks can be tinted various redish hues by selecting different colors in the color palette.', - 'author'=>$AUTHOR_ALBERT), + 'author'=>$AUTHOR_ALBERT, + 'see'=>'Pixels'), array('name'=>'Calligraphy', 'desc'=>'This paints on the canvas with a calligraphy pen. The quicker you move, the thinner the lines.', @@ -79,6 +80,10 @@ $tools = array( 'desc'=>'This makes parts of the picture (where you move the mouse) look like a chalk drawing.', 'author'=>$AUTHOR_KENDRICK), + array('name'=>'Clone', + 'desc'=>'Clone (copy, via painting) part of the picture. Click ones to choose the source, then click and drag to clone it elsewhere in the drawing. Once you release, click to choose another source and start again.', + 'author'=>$AUTHOR_KENDRICK), + array('name'=>'Color and White', 'desc'=>'This makes parts of your picture two colors: white, and the color chosen in the palette. (i.e., if you choose black, you\'ll get a black and white picture).', 'author'=>$AUTHOR_ANDREWC), @@ -226,6 +231,11 @@ $tools = array( 'author'=>$AUTHOR_ADAMR, 'see'=>'Rosette', 'Kaleidoscope'), + array('name'=>'Pixels', + 'desc'=>'Draw large square "pixels" on the canvas.', + 'author'=>$AUTHOR_KENDRICK, + 'see'=>'Bricks'), + array('name'=>'Puzzle', 'desc'=>'Slide parts of your picture around like a sliding puzzle.', 'author'=>$AUTHOR_ADAMR), @@ -372,11 +382,11 @@ foreach ($tools as $t) { $out .= "

    By "; if (is_array($t['author'])) { foreach ($t['author'] as $a) { - list($authname, $authemail) = split('\|', $a); + list($authname, $authemail) = explode('|', $a); $out .= $authname." <".$authemail.">
    \n"; } } else { - list($authname, $authemail) = split('\|', $t['author']); + list($authname, $authemail) = explode('|', $t['author']); $out .= $authname." <".$authemail.">"; } diff --git a/magic/src/clone.c b/magic/src/clone.c new file mode 100644 index 000000000..5d0e30e2b --- /dev/null +++ b/magic/src/clone.c @@ -0,0 +1,256 @@ +/* + clone.c + + Clone tool paintbrush Magic Tools Plugin + Tux Paint - A simple drawing program for children. + + Copyright (c) 2021 by Bill Kendrick and others; see AUTHORS.txt + bill@newbreedsoftware.com + http://www.tuxpaint.org/ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + (See COPYING.txt) + + Last updated: January 10, 2021 + $Id$ +*/ + +#include +#include +#include +#include "tp_magic_api.h" +#include "SDL_image.h" +#include "SDL_mixer.h" + +/* What tools we contain: */ + +enum +{ + TOOL_CLONE, + NUM_TOOLS +}; + + +/* Tool states: */ + +enum +{ + CLONE_READY_TO_START, + CLONE_STARTING, + CLONE_CLONING +}; + + +/* Our globals: */ + +static Mix_Chunk *clone_snd; +int clone_state; +int clone_src_x, clone_src_y; +int clone_drag_start_x, clone_drag_start_y; + + +/* Local function prototype: */ + +int clone_init(magic_api * api); +Uint32 clone_api_version(void); +int clone_get_tool_count(magic_api * api); +SDL_Surface *clone_get_icon(magic_api * api, int which); +char *clone_get_name(magic_api * api, int which); +char *clone_get_description(magic_api * api, int which, int mode); +void clone_drag(magic_api * api, int which, SDL_Surface * canvas, + SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect); +void clone_click(magic_api * api, int which, int mode, + SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect); +void clone_release(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect); +void clone_shutdown(magic_api * api); +void clone_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); +int clone_requires_colors(magic_api * api, int which); +void clone_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); +void clone_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); +int clone_modes(magic_api * api, int which); + +// No setup required: +int clone_init(magic_api * api) +{ + char fname[1024]; + + snprintf(fname, sizeof(fname), "%s/sounds/magic/clone.ogg", api->data_directory); + clone_snd = Mix_LoadWAV(fname); + + clone_state = CLONE_READY_TO_START; + + return (1); +} + +Uint32 clone_api_version(void) +{ + return (TP_MAGIC_API_VERSION); +} + +// We have multiple tools: +int clone_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) +{ + return (NUM_TOOLS); +} + +// Load our icons: +SDL_Surface *clone_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) +{ + char fname[1024]; + + snprintf(fname, sizeof(fname), "%s/images/magic/clone.png", api->data_directory); + + return (IMG_Load(fname)); +} + +// Return our names, localized: +char *clone_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) +{ + return (strdup(gettext_noop("Clone"))); +} + +// Return our descriptions, localized: +char *clone_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) +{ + return (strdup(gettext_noop("Click once to pick a spot to begin cloning. Click again and drag to clone that part of the picture."))); + + return (NULL); +} + +// Do the effect: + +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 srcx, srcy; + Uint32 pixel; + + srcx = clone_src_x + (x - clone_drag_start_x); + srcy = clone_src_y + (y - clone_drag_start_y); + + for (yy = -16; yy < 16; 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); + } + } + } +} + +// Affect the canvas on drag: +void clone_drag(magic_api * api, int which, SDL_Surface * canvas, + SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect) +{ + if (clone_state != CLONE_CLONING) + return; + + clone_drag_start_x = ox; + clone_drag_start_y = oy; + + api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_clone); +// do_clone((void *)api, which, canvas, last, x, y); + + clone_src_x += (x - ox); + clone_src_y += (y - oy); + + if (ox > x) + { + int tmp = ox; + + ox = x; + x = tmp; + } + if (oy > y) + { + int tmp = oy; + + oy = y; + y = tmp; + } + + 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->h; + + api->playsound(clone_snd, (x * 255) / canvas->w, 255); +} + +// Affect the canvas on click: +void clone_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, + SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect) +{ + if (clone_state == CLONE_READY_TO_START) { + clone_src_x = x; + clone_src_y = y; + clone_state = CLONE_STARTING; + } else if (clone_state == CLONE_CLONING) { + clone_drag(api, which, canvas, last, x, y, x, y, update_rect); + } +} + +void clone_release(magic_api * api, int which ATTRIBUTE_UNUSED, + SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED, + int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) +{ + if (clone_state == CLONE_STARTING) { + clone_state = CLONE_CLONING; + } else { + clone_state = CLONE_READY_TO_START; + } + api->stopsound(); +} + +// No setup happened: +void clone_shutdown(magic_api * api ATTRIBUTE_UNUSED) +{ + if (clone_snd != NULL) + Mix_FreeChunk(clone_snd); +} + +// Record the color from Tux Paint: +void clone_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 ATTRIBUTE_UNUSED r, Uint8 ATTRIBUTE_UNUSED g, Uint8 ATTRIBUTE_UNUSED b) +{ +} + +// Use colors: +int clone_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) +{ + return 0; +} + +void clone_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, + int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) +{ + clone_state = CLONE_READY_TO_START; +} + +void clone_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, + int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) +{ + clone_state = CLONE_READY_TO_START; +} + +int clone_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) +{ + return (MODE_PAINT); +}