"Opposite" Magic tool: Complementary colors

Closes https://sourceforge.net/p/tuxpaint/feature-requests/136/
This commit is contained in:
Bill Kendrick 2021-09-06 01:36:08 -07:00
parent 78ea74b5b3
commit fa23c099f2
137 changed files with 9176 additions and 6533 deletions

BIN
magic/icons/opposite.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View file

@ -39,6 +39,7 @@
<li><a href="square_mosaic.html">Square Mosaic</a></li>
<li><a href="negative.html">Negative</a></li>
<li><a href="noise.html">Noise</a></li>
<li><a href="opposite.html">Opposite</a></li>
<li><a href="panels.html">Panels</a></li>
<li><a href="pattern.html">Pattern</a></li>
<li><a href="perspective.html">Perspective</a></li>

View file

@ -5,5 +5,5 @@
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#FF0000" alink="#FF00FF">
<h1 align="center">Tux Paint "Magic" Tool: Negative</h1>
<h2 align="center">By Bill Kendrick &lt;<a href="mailto:bill@newbreedsoftware.com">bill@newbreedsoftware.com</a>&gt;</h2>
<p>This inverts the colors wherever you drag the mouse. (e.g., white becomes black, and vice versa.)</p>
<p>This inverts the colors wherever you drag the mouse. (e.g., white becomes black, and vice versa.) It inverts the values of the Red, Green, and Blue components of the pixels.</p>
</body></html>

View file

@ -0,0 +1,9 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<body><html><head><title>Tux Paint "Magic" Tool: Opposite</title>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
</head>
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#FF0000" alink="#FF00FF">
<h1 align="center">Tux Paint "Magic" Tool: Opposite</h1>
<h2 align="center">By Bill Kendrick &lt;<a href="mailto:bill@newbreedsoftware.com">bill@newbreedsoftware.com</a>&gt;</h2>
<p>This converts the colors wherever you drag the mouse into their complementary (opposite) colors. (e.g., blue becomes orange, and vice versa.) It changes the Hue compoment of the pixels, without affecting the Saturation or Lightness.</p>
</body></html>

View file

@ -5,7 +5,7 @@ individual HTML files for each of them, and an index.html that links to
them all. */
/* Bill Kendrick <bill@newbreedsoftware.com> */
/* Oct. 8, 2009 - February 15, 2020 */
/* Oct. 8, 2009 - September 6, 2021 */
/* Authors of the Magic tools: */
@ -214,13 +214,17 @@ $tools = array(
)),
array('name'=>'Negative',
'desc'=>'This inverts the colors wherever you drag the mouse. (e.g., white becomes black, and vice versa.)',
'desc'=>'This inverts the colors wherever you drag the mouse. (e.g., white becomes black, and vice versa.) It inverts the values of the Red, Green, and Blue components of the pixels.',
'author'=>$AUTHOR_KENDRICK),
array('name'=>'Noise',
'desc'=>'Add random noise and static to your picture.',
'author'=>$AUTHOR_ANDREWC),
array('name'=>'Opposite',
'desc'=>'This converts the colors wherever you drag the mouse into their complementary (opposite) colors. (e.g., blue becomes orange, and vice versa.) It changes the Hue compoment of the pixels, without affecting the Saturation or Lightness.',
'author'=>$AUTHOR_KENDRICK),
array('name'=>'Panels',
'desc'=>'Shrink the image and repeat it four times in a 2-by-2 grid. Useful for creating 4-panel comics. Can also be used to create a compound-eye effect.',
'author'=>$AUTHOR_KENDRICK),

View file

@ -23,7 +23,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
(See COPYING.txt)
Last updated: September 4, 2021
Last updated: September 6, 2021
$Id$
*/
@ -56,7 +56,35 @@ void negative_switchin(magic_api * api, int which, int mode, SDL_Surface * canva
void negative_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
int negative_modes(magic_api * api, int which);
// No setup required:
enum
{
TOOL_NEGATIVE,
TOOL_COMPLEMENTARY,
negative_NUM_TOOLS
};
const char *negative_icon_filenames[negative_NUM_TOOLS] = {
"negative.png",
"opposite.png"
};
const char *negative_names[negative_NUM_TOOLS] = {
gettext_noop("Negative"),
gettext_noop("Opposite")
};
const char *negative_descs[negative_NUM_TOOLS][2] = {
{
gettext_noop("Click and drag the mouse around to make your painting negative."),
gettext_noop("Click to turn your painting into its negative.")
},
{
gettext_noop("Click and drag the mouse around to change colors to their opposites -- their complementary colors."),
gettext_noop("Click to turn all colors in your painting into their opposites -- their complementary colors.")
},
};
int negative_init(magic_api * api)
{
char fname[1024];
@ -73,43 +101,69 @@ Uint32 negative_api_version(void)
return (TP_MAGIC_API_VERSION);
}
// Only one tool:
int negative_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
{
return (1);
return (negative_NUM_TOOLS);
}
// Load our icon:
SDL_Surface *negative_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
SDL_Surface *negative_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/negative.png", api->data_directory);
snprintf(fname, sizeof(fname), "%s/images/magic/%s", api->data_directory, negative_icon_filenames[which]);
return (IMG_Load(fname));
}
// Return our name, localized:
char *negative_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
char *negative_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
{
return (strdup(gettext_noop("Negative")));
return (strdup(gettext_noop(negative_names[which])));
}
// Return our description, localized:
char *negative_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode)
char *negative_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode)
{
if (mode == MODE_PAINT)
return (strdup(gettext_noop("Click and drag the mouse around to make your painting negative."))); /* Does this make more sense? */
else if (mode == MODE_FULLSCREEN)
return (strdup(gettext_noop("Click to turn your painting into its negative.")));
int mode_idx;
if (mode == MODE_PAINT) {
mode_idx = 0;
} else if (mode == MODE_FULLSCREEN) {
mode_idx = 1;
} else {
return NULL;
}
return(strdup(gettext_noop(negative_descs[which][mode_idx])));
}
static void negative_calc(void *ptr, int which, Uint8 r, Uint8 g, Uint8 b, Uint8 * new_r, Uint8 * new_g, Uint8 * new_b) {
float h, s, v, new_h;
magic_api *api = (magic_api *) ptr;
if (which == TOOL_NEGATIVE)
{
*new_r = 0xFF - r;
*new_g = 0xFF - g;
*new_b = 0xFF - b;
}
else
return (NULL);
{
api->rgbtohsv(r, g, b, &h, &s, &v);
new_h = h + 180.0;
if (new_h >= 360.0)
{
new_h = new_h - 360.0;
}
api->hsvtorgb(new_h, s, v, new_r, new_g, new_b);
}
}
// Callback that does the negative color effect on a circle centered around x,y
static void do_negative(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
static void do_negative(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
{
int xx, yy;
Uint8 r, g, b;
Uint8 r, g, b, new_r, new_g, new_b;
magic_api *api = (magic_api *) ptr;
for (yy = y - 16; yy < y + 16; yy++)
@ -119,12 +173,8 @@ static void do_negative(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * can
if (api->in_circle(xx - x, yy - y, 16))
{
SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b);
r = 0xFF - r;
g = 0xFF - g;
b = 0xFF - b;
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b));
negative_calc(api, which, r, g, b, &new_r, &new_g, &new_b);
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, new_r, new_g, new_b));
}
}
}
@ -175,19 +225,15 @@ void negative_click(magic_api * api, int which, int mode,
else
{
int xx, yy;
Uint8 r, g, b;
Uint8 r, g, b, new_r, new_g, new_b;
for (yy = 0; yy < canvas->h; yy++)
{
for (xx = 0; xx < canvas->w; xx++)
{
SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b);
r = 0xFF - r;
g = 0xFF - g;
b = 0xFF - b;
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b));
negative_calc(api, which, r, g, b, &new_r, &new_g, &new_b);
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, new_r, new_g, new_b));
}
}
@ -240,3 +286,4 @@ int negative_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
{
return (MODE_PAINT | MODE_FULLSCREEN);
}