diff --git a/Makefile b/Makefile index 4883ae54d..7f52fe20e 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ # Tux Paint - A simple drawing program for children. -# Copyright (c) 2002-2020 +# Copyright (c) 2002-2021 # Various contributors (see AUTHORS.txt) # http://www.tuxpaint.org/ -# June 14, 2002 - December 27, 2020 +# June 14, 2002 - January 2, 2020 # The version number, for release: @@ -15,7 +15,7 @@ ifdef SOURCE_DATE_EPOCH else VER_DATE=$(shell date "+%Y-%m-%d") endif -MAGIC_API_VERSION:=0x00000003 +MAGIC_API_VERSION:=0x00000004 # Need to know the OS diff --git a/docs/CHANGES.txt b/docs/CHANGES.txt index 747d64eb9..acc5c2bb6 100644 --- a/docs/CHANGES.txt +++ b/docs/CHANGES.txt @@ -18,6 +18,8 @@ $Id$ for the color palette at the bottom of the screen. (Use the "colorsrows" option.) Pere Pujal i Carabantes + + * A new "xorpixel()" function has been added to the Magic Tools API. * New Magic Tools: ---------------- diff --git a/magic/docs/en/README.txt b/magic/docs/en/README.txt index 4e9418868..f5173ae38 100644 --- a/magic/docs/en/README.txt +++ b/magic/docs/en/README.txt @@ -3,7 +3,7 @@ Copyright 2007-2018 by various contributors; see AUTHORS.txt http://www.tuxpaint.org/ - July 5, 2007 - August 30, 2018 + July 5, 2007 - February 20, 2021 ---------------------------------------------------------------------- @@ -392,6 +392,13 @@ Interfaces RGB values to a Uint32 'pixel' value appropriate to the destination surface.) + * Uint32 xorpixel(SDL_Surface * surf, int x, int y) + Applies an XOR (exclusive-or) operation to the pixel at + coordinates (x,y) of the SDL_Surface. Applying an XOR again at + the same position will return the pixel to the original value. + Useful for displaying temporary 'rubberband' lines, outlines, + and crosshairs, while utilizing a Magic Tool. + * SDL_Surface * scale(SDL_Surface * surf, int w, int h, int keep_aspect) This accepts an existing SDL surface and creates a new one @@ -648,12 +655,12 @@ Compiling A snippet from a Makefile to compile a Tux Paint "Magic" tool plugin might look like this: - +----------------------------------------------------------------+ - | CFLAGS=-Wall -O2 $(shell tp-magic-config --cflags) | - | | - | my_plugin.so: my_plugin.c | - | gcc -shared $(CFLAGS) -o my_plugin.so my_plugin.c | - +----------------------------------------------------------------+ + +------------------------------------------------------+ + | CFLAGS=-Wall -O2 $(shell tp-magic-config --cflags) | + | | + | my_plugin.so: my_plugin.c | + | gcc -shared $(CFLAGS) -o my_plugin.so my_plugin.c | + +------------------------------------------------------+ The first line sets up Makefile variable ("CFLAGS") that contains flags for the compiler. "-Wall" asks for all compiler warnings to be @@ -683,15 +690,15 @@ Compiling An even more generalized Makefile might look like this: - +----------------------------------------------------------------+ - | CFLAGS=-Wall -O2 $(shell tp-magic-config --cflags) | - | | - | my_plugin_1.so: my_plugin_1.c | - | $(CC) -shared $(CFLAGS) -o $@ $< | - | | - | my_plugin_2.so: my_plugin_2.c | - | $(CC) -shared $(CFLAGS) -o $@ $< | - +----------------------------------------------------------------+ + +----------------------------------------------------+ + | CFLAGS=-Wall -O2 $(shell tp-magic-config --cflags) | + | | + | my_plugin_1.so: my_plugin_1.c | + | $(CC) -shared $(CFLAGS) -o $@ $< | + | | + | my_plugin_2.so: my_plugin_2.c | + | $(CC) -shared $(CFLAGS) -o $@ $< | + +----------------------------------------------------+ As before, there are lines that define the command "make" should run when it determines that it needs to (re)compile the ".so" file(s). @@ -799,35 +806,35 @@ Installing A snippet from a more generalized Makefile might look like this: - +----------------------------------------------------------------+ - | PLUGINPREFIX=$(shell tp-magic-config --pluginprefix) | - | PLUGINDOCPREFIX=$(shell tp-magic-config --plugindocprefix) | - | DATAPREFIX=$(shell tp-magic-config --dataprefix) | - | | - | install: | - | # | - | # Install plugin | - | mkdir -p $(PLUGINPREFIX) | - | cp *.so $(PLUGINPREFIX)/ | - | chmod 644 $(PLUGINPREFIX)/*.so | - | # | - | # Install icons | - | mkdir -p $(DATAPREFIX)/images/magic | - | cp icons/*.png $(DATAPREFIX)/images/magic/ | - | chmod 644 $(DATAPREFIX)/images/magic/*.png | - | # | - | # Install sound effects | - | mkdir -p $(DATAPREFIX)/sounds/magic | - | cp sounds/*.ogg $(DATAPREFIX)/sounds/magic/ | - | chmod 644 $(DATAPREFIX)/sounds/magic/*.ogg | - | # | - | # Install docs | - | mkdir -p $(PLUGINDOCPREFIX)/html | - | cp docs/*.html $(PLUGINDOCPREFIX)/html/ | - | cp docs/*.txt $(PLUGINDOCPREFIX)/ | - | chmod 644 $(PLUGINDOCPREFIX)/html/*.html | - | chmod 644 $(PLUGINDOCPREFIX)/*.txt | - +----------------------------------------------------------------+ + +------------------------------------------------------------+ + | PLUGINPREFIX=$(shell tp-magic-config --pluginprefix) | + | PLUGINDOCPREFIX=$(shell tp-magic-config --plugindocprefix) | + | DATAPREFIX=$(shell tp-magic-config --dataprefix) | + | | + | install: | + | # | + | # Install plugin | + | mkdir -p $(PLUGINPREFIX) | + | cp *.so $(PLUGINPREFIX)/ | + | chmod 644 $(PLUGINPREFIX)/*.so | + | # | + | # Install icons | + | mkdir -p $(DATAPREFIX)/images/magic | + | cp icons/*.png $(DATAPREFIX)/images/magic/ | + | chmod 644 $(DATAPREFIX)/images/magic/*.png | + | # | + | # Install sound effects | + | mkdir -p $(DATAPREFIX)/sounds/magic | + | cp sounds/*.ogg $(DATAPREFIX)/sounds/magic/ | + | chmod 644 $(DATAPREFIX)/sounds/magic/*.ogg | + | # | + | # Install docs | + | mkdir -p $(PLUGINDOCPREFIX)/html | + | cp docs/*.html $(PLUGINDOCPREFIX)/html/ | + | cp docs/*.txt $(PLUGINDOCPREFIX)/ | + | chmod 644 $(PLUGINDOCPREFIX)/html/*.html | + | chmod 644 $(PLUGINDOCPREFIX)/*.txt | + +------------------------------------------------------------+ The first three lines set up Makefile variables that contain the paths returned by the "tp-magic-config" command-line tool. (The diff --git a/magic/docs/en/html/README.html b/magic/docs/en/html/README.html index a83ffa026..e6fcd52ef 100644 --- a/magic/docs/en/html/README.html +++ b/magic/docs/en/html/README.html @@ -12,7 +12,7 @@ alink="#FF00FF">

Copyright 2007-2018 by various contributors; see AUTHORS.txt
http://www.tuxpaint.org/

-

July 5, 2007 - August 30, 2018

+

July 5, 2007 - February 20, 2021


@@ -497,6 +497,15 @@ plugin's functions. surface.)

+
  • Uint32 xorpixel(SDL_Surface * surf, + int x, int y)
    + Applies an XOR (exclusive-or) operation to the pixel at coordinates + (x,y) of the SDL_Surface. Applying an XOR again at the same position + will return the pixel to the original value. Useful for displaying + temporary 'rubberband' lines, outlines, and crosshairs, while + utilizing a Magic Tool.
    +
    +
  • SDL_Surface * scale(SDL_Surface * surf, int w, int h, int keep_aspect)
    This accepts an existing SDL surface and creates a new one scaled to an diff --git a/src/tp_magic_api.h.in b/src/tp_magic_api.h.in index 0366b8bc1..d8c816573 100644 --- a/src/tp_magic_api.h.in +++ b/src/tp_magic_api.h.in @@ -110,6 +110,9 @@ typedef struct magic_api_t { SDL_MustLockSurface() can tell you whether a surface needs to be locked. */ void (*putpixel)(SDL_Surface *, int, int, Uint32); + /* XOR's the pixel at (x,y) location of the surface. */ + Uint32 (*xorpixel)(SDL_Surface *, int, int); + /* Asks Tux Paint to play a sound (one loaded via SDL_mixer library); the first value is for left/right panning (0 is left, 128 is center, 255 is right); the second value is for total volume (0 is off, 255 is diff --git a/src/tuxpaint.c b/src/tuxpaint.c index 867199352..99b4462aa 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 - January 26, 2021 + June 14, 2002 - February 20, 2021 */ @@ -751,6 +751,7 @@ static int WINDOW_HEIGHT = 600; static void magic_putpixel(SDL_Surface * surface, int x, int y, Uint32 pixel); static Uint32 magic_getpixel(SDL_Surface * surface, int x, int y); +static void magic_xorpixel(SDL_Surface * surface, int x, int y); /** * Sets a variety of screen layout globals, based on the @@ -1915,6 +1916,7 @@ static void draw_none(void); static void do_undo(void); static void do_redo(void); static void render_brush(void); +static void _xorpixel(SDL_Surface * surf, int x, int y); static void line_xor(int x1, int y1, int x2, int y2); static void rect_xor(int x1, int y1, int x2, int y2); static void draw_blinking_cursor(void); @@ -9920,32 +9922,26 @@ static SDL_Surface *zoom(SDL_Surface * src, int new_w, int new_h) #endif -/** - * FIXME - */ /* XOR must show up on black, white, 0x7f grey, and 0x80 grey. XOR must be exactly 100% perfectly reversable. */ -static void xorpixel(int x, int y) +static void _xorpixel(SDL_Surface * surf, int x, int y) { Uint8 *p; int BytesPerPixel; /* if outside the canvas, return */ - if ((unsigned)x >= (unsigned)canvas->w || (unsigned)y >= (unsigned)canvas->h) + if (x < 0 || x >= surf->w || y < 0 || y >= surf->h) return; - /* now switch to screen coordinates */ - x += r_canvas.x; - y += r_canvas.y; /* Always 4, except 3 when loading a saved image. */ - BytesPerPixel = screen->format->BytesPerPixel; + BytesPerPixel = surf->format->BytesPerPixel; /* Set a pointer to the exact location in memory of the pixel */ - p = (Uint8 *) (((Uint8 *) screen->pixels) + /* Start: beginning of RAM */ - (y * screen->pitch) + /* Go down Y lines */ + p = (Uint8 *) (((Uint8 *) surf->pixels) + /* Start: beginning of RAM */ + (y * surf->pitch) + /* Go down Y lines */ (x * BytesPerPixel)); /* Go in X pixels */ - /* XOR the (correctly-sized) piece of data in the screen's RAM */ + /* XOR the (correctly-sized) piece of data in the surface's RAM */ if (likely(BytesPerPixel == 4)) *(Uint32 *) p ^= 0x80808080u; /* 32-bit display */ else if (BytesPerPixel == 1) @@ -9960,6 +9956,21 @@ static void xorpixel(int x, int y) } } +/** + * FIXME + */ +static void xorpixel(int x, int y) { + /* if outside the canvas, return */ + if ((unsigned)x >= (unsigned)canvas->w || (unsigned)y >= (unsigned)canvas->h) + return; + + /* now switch to screen coordinates */ + x += r_canvas.x; + y += r_canvas.y; + + _xorpixel(screen, x, y); +} + /** * FIXME @@ -18655,6 +18666,7 @@ static void load_magic_plugins(void) magic_api_struct->in_circle = in_circle_rad; magic_api_struct->getpixel = magic_getpixel; magic_api_struct->putpixel = magic_putpixel; + magic_api_struct->xorpixel = magic_xorpixel; magic_api_struct->line = magic_line_func; magic_api_struct->playsound = magic_playsound; magic_api_struct->stopsound = magic_stopsound; @@ -21301,6 +21313,14 @@ static Uint32 magic_getpixel(SDL_Surface * surface, int x, int y) return (getpixels[surface->format->BytesPerPixel] (surface, x, y)); } +/** + * FIXME + */ +static void magic_xorpixel(SDL_Surface * surface, int x, int y) +{ + _xorpixel(surface, x, y); +} + /** * FIXME