WIP ASCII art Magic tools; code working!
This commit is contained in:
parent
6a591a2ef1
commit
c9f978b1ca
7 changed files with 181 additions and 35 deletions
|
|
@ -6,7 +6,7 @@ Copyright (c) 2002-2024
|
||||||
Various contributors (see below, and CHANGES.txt)
|
Various contributors (see below, and CHANGES.txt)
|
||||||
https://tuxpaint.org/
|
https://tuxpaint.org/
|
||||||
|
|
||||||
June 17, 2002 - September 24, 2024
|
June 17, 2002 - September 26, 2024
|
||||||
|
|
||||||
* Design and Coding:
|
* Design and Coding:
|
||||||
|
|
||||||
|
|
@ -197,6 +197,22 @@ June 17, 2002 - September 24, 2024
|
||||||
<https://freesound.org/people/lorefold/sounds/607310/>
|
<https://freesound.org/people/lorefold/sounds/607310/>
|
||||||
Creative Commons 0 by lorefold <https://freesound.org/people/lorefold/>
|
Creative Commons 0 by lorefold <https://freesound.org/people/lorefold/>
|
||||||
|
|
||||||
|
"ASCII Typewriter" & "ASCII Computer" magic tools
|
||||||
|
by Bill Kendrick <bill@newbreedsoftware.com>
|
||||||
|
|
||||||
|
"ASCII Computer" font: IBM CGA Adapter
|
||||||
|
taken from "Typography in 16-bits: System fonts" by Damien Guard
|
||||||
|
<https://damieng.com/blog/2011/03/27/typography-in-16-bits-system-fonts/>
|
||||||
|
|
||||||
|
"ASCII Typewriter" font based on: "Patrician"
|
||||||
|
<https://site.xavier.edu/polt/typewriters/patrician.html>
|
||||||
|
Creative Commons CC0 1.0 Universal
|
||||||
|
by Richard Polt (based on a 1959 Royal FP typewriter)
|
||||||
|
And using a subset of characters taken from
|
||||||
|
"Character representation of grey scale images"
|
||||||
|
<https://paulbourke.net/dataformats/asciiart/>
|
||||||
|
by Paul Bourke
|
||||||
|
|
||||||
Bloom magic tool
|
Bloom magic tool
|
||||||
by Bill Kendrick <bill@newbreedsoftware.com>
|
by Bill Kendrick <bill@newbreedsoftware.com>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ Copyright (c) 2002-2024
|
||||||
Various contributors (see below, and AUTHORS.txt)
|
Various contributors (see below, and AUTHORS.txt)
|
||||||
https://tuxpaint.org/
|
https://tuxpaint.org/
|
||||||
|
|
||||||
2024.September.25 (0.9.34)
|
2024.September.26 (0.9.34)
|
||||||
* New Magic Tools:
|
* New Magic Tools:
|
||||||
----------------
|
----------------
|
||||||
* "Comic Dots", draws repeating dots (using a multiply blend)
|
* "Comic Dots", draws repeating dots (using a multiply blend)
|
||||||
|
|
@ -31,6 +31,25 @@ https://tuxpaint.org/
|
||||||
<https://freesound.org/people/DigitalUnderglow/>
|
<https://freesound.org/people/DigitalUnderglow/>
|
||||||
+ Closes https://sourceforge.net/p/tuxpaint/feature-requests/260/
|
+ Closes https://sourceforge.net/p/tuxpaint/feature-requests/260/
|
||||||
|
|
||||||
|
* WIP "ASCII Typewriter" & "ASCII Computer", turn your drawing into
|
||||||
|
ASCII art.
|
||||||
|
+ TODO Sound effects
|
||||||
|
+ TODO Icons
|
||||||
|
+ TODO Documentation
|
||||||
|
+ Code by Bill Kendrick <bill@newbreedsoftware.com>
|
||||||
|
+ Computer font: IBM CGA Adapter
|
||||||
|
taken from "Typography in 16-bits: System fonts"
|
||||||
|
<https://damieng.com/blog/2011/03/27/typography-in-16-bits-system-fonts/>
|
||||||
|
by Damien Guard
|
||||||
|
+ Typewriter font based on: "Patrician"
|
||||||
|
<https://site.xavier.edu/polt/typewriters/patrician.html>
|
||||||
|
Creative Commons CC0 1.0 Universal
|
||||||
|
by Richard Polt (based on a 1959 Royal FP typewriter)
|
||||||
|
And using a subset of characters taken from
|
||||||
|
"Character representation of grey scale images"
|
||||||
|
<https://paulbourke.net/dataformats/asciiart/>
|
||||||
|
by Paul Bourke
|
||||||
|
|
||||||
* Magic Tool Improvements:
|
* Magic Tool Improvements:
|
||||||
------------------------
|
------------------------
|
||||||
* Sound pause/resume functions added to API
|
* Sound pause/resume functions added to API
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 13 KiB |
|
|
@ -22,9 +22,17 @@
|
||||||
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: September 25, 2024
|
Last updated: September 26, 2024
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//#define DEBUG
|
||||||
|
|
||||||
|
#if defined(DEBUG)
|
||||||
|
#define DEBUG_PRINTF(...) printf(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define DEBUG_PRINTF(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "tp_magic_api.h"
|
#include "tp_magic_api.h"
|
||||||
|
|
@ -38,8 +46,8 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
char * ascii_tool_names[NUM_TOOLS] = {
|
char * ascii_tool_names[NUM_TOOLS] = {
|
||||||
"Typewriter",
|
gettext_noop("Typewriter"),
|
||||||
"Computer",
|
gettext_noop("Computer"),
|
||||||
};
|
};
|
||||||
|
|
||||||
char * ascii_tool_filenames[NUM_TOOLS] = {
|
char * ascii_tool_filenames[NUM_TOOLS] = {
|
||||||
|
|
@ -91,6 +99,8 @@ Uint8 ascii_default_size(magic_api * api, int which, int mode);
|
||||||
void ascii_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * last, Uint8 size,
|
void ascii_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * last, Uint8 size,
|
||||||
SDL_Rect * update_rect);
|
SDL_Rect * update_rect);
|
||||||
void do_ascii_effect(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
|
void do_ascii_effect(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
|
||||||
|
int get_best_char(int which, int brightness);
|
||||||
|
int get_bright(magic_api * api, int r, int g, int b);
|
||||||
|
|
||||||
|
|
||||||
Uint32 ascii_api_version(void)
|
Uint32 ascii_api_version(void)
|
||||||
|
|
@ -101,9 +111,11 @@ Uint32 ascii_api_version(void)
|
||||||
int ascii_init(magic_api * api, Uint8 disabled_features ATTRIBUTE_UNUSED, Uint8 complexity_level ATTRIBUTE_UNUSED)
|
int ascii_init(magic_api * api, Uint8 disabled_features ATTRIBUTE_UNUSED, Uint8 complexity_level ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
char fname[1024];
|
char fname[1024];
|
||||||
int i, j, x, y, xx, w, num_chars, all_clear, area, bright;
|
int i, j, x, y, xx, w, num_chars, all_clear, area, bright, clear_brightness;
|
||||||
|
int min_bright, max_bright;
|
||||||
Uint32 clear_pixel, pixel;
|
Uint32 clear_pixel, pixel;
|
||||||
Uint8 r, g, b;
|
Uint8 r, g, b;
|
||||||
|
Uint8 clear_r, clear_g, clear_b;
|
||||||
|
|
||||||
for (i = 0; i < NUM_TOOLS; i++)
|
for (i = 0; i < NUM_TOOLS; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -129,12 +141,14 @@ int ascii_init(magic_api * api, Uint8 disabled_features ATTRIBUTE_UNUSED, Uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
clear_pixel = api->getpixel(ascii_bitmap[i], 0, 0);
|
clear_pixel = api->getpixel(ascii_bitmap[i], 0, 0);
|
||||||
// printf("%s; clear pixel %d\n", fname, clear_pixel);
|
SDL_GetRGB(clear_pixel, ascii_bitmap[i]->format, &clear_r, &clear_g, &clear_b);
|
||||||
|
DEBUG_PRINTF("%s; clear pixel %d (%d,%d,%d)\n", fname, clear_pixel, clear_r, clear_g, clear_b);
|
||||||
|
clear_brightness = (clear_r + clear_g + clear_b) / 3;
|
||||||
|
|
||||||
num_chars = 0;
|
num_chars = 0;
|
||||||
for (x = 0; x < ascii_bitmap[i]->w; x++)
|
for (x = 0; x < ascii_bitmap[i]->w; x++)
|
||||||
{
|
{
|
||||||
ascii_char_x[i][num_chars] = x;
|
/* Skip whitespace between characters */
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
all_clear = 1;
|
all_clear = 1;
|
||||||
|
|
@ -148,6 +162,9 @@ int ascii_init(magic_api * api, Uint8 disabled_features ATTRIBUTE_UNUSED, Uint8
|
||||||
}
|
}
|
||||||
while (all_clear && x < ascii_bitmap[i]->w);
|
while (all_clear && x < ascii_bitmap[i]->w);
|
||||||
|
|
||||||
|
ascii_char_x[i][num_chars] = x;
|
||||||
|
|
||||||
|
/* Capture the extent of the character */
|
||||||
all_clear = 0;
|
all_clear = 0;
|
||||||
for (xx = x; xx < ascii_bitmap[i]->w && !all_clear; xx++)
|
for (xx = x; xx < ascii_bitmap[i]->w && !all_clear; xx++)
|
||||||
{
|
{
|
||||||
|
|
@ -164,26 +181,26 @@ int ascii_init(magic_api * api, Uint8 disabled_features ATTRIBUTE_UNUSED, Uint8
|
||||||
/* Magenta counts as a connecting pixel, but we
|
/* Magenta counts as a connecting pixel, but we
|
||||||
* want it to appear as the clear color */
|
* want it to appear as the clear color */
|
||||||
api->putpixel(ascii_bitmap[i], xx, y, clear_pixel);
|
api->putpixel(ascii_bitmap[i], xx, y, clear_pixel);
|
||||||
// printf("x");
|
DEBUG_PRINTF("x");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// printf("#");
|
DEBUG_PRINTF("#");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// printf("-");
|
DEBUG_PRINTF("-");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// printf("\n");
|
DEBUG_PRINTF("\n");
|
||||||
}
|
}
|
||||||
x = xx;
|
x = xx - 1;
|
||||||
num_chars++;
|
num_chars++;
|
||||||
// printf(".......................................\n");
|
DEBUG_PRINTF(".......................................\n");
|
||||||
}
|
}
|
||||||
ascii_num_chars[i] = num_chars;
|
ascii_num_chars[i] = num_chars;
|
||||||
printf("%s has %d characters\n", fname, num_chars);
|
DEBUG_PRINTF("%s has %d characters\n", fname, num_chars);
|
||||||
|
|
||||||
/* Determine the max. width of any character */
|
/* Determine the max. width of any character */
|
||||||
ascii_char_x[i][num_chars] = x;
|
ascii_char_x[i][num_chars] = x;
|
||||||
|
|
@ -191,7 +208,7 @@ int ascii_init(magic_api * api, Uint8 disabled_features ATTRIBUTE_UNUSED, Uint8
|
||||||
for (j = 0; j < num_chars; j++)
|
for (j = 0; j < num_chars; j++)
|
||||||
{
|
{
|
||||||
w = ascii_char_x[i][j + 1] - ascii_char_x[i][j];
|
w = ascii_char_x[i][j + 1] - ascii_char_x[i][j];
|
||||||
// printf("%d->%d = %d\n", j, j + 1, w);
|
DEBUG_PRINTF("%d->%d = %d\n", j, j + 1, w);
|
||||||
if (w > ascii_char_maxwidth[i])
|
if (w > ascii_char_maxwidth[i])
|
||||||
{
|
{
|
||||||
ascii_char_maxwidth[i] = w;
|
ascii_char_maxwidth[i] = w;
|
||||||
|
|
@ -201,7 +218,7 @@ int ascii_init(magic_api * api, Uint8 disabled_features ATTRIBUTE_UNUSED, Uint8
|
||||||
/* Calculate the intensity of each character */
|
/* Calculate the intensity of each character */
|
||||||
area = ascii_char_maxwidth[i] * ascii_bitmap[i]->h;
|
area = ascii_char_maxwidth[i] * ascii_bitmap[i]->h;
|
||||||
|
|
||||||
// printf("%s max char width is %d -- * %d = area %d\n", fname, ascii_char_maxwidth[i], ascii_bitmap[i]->h, area);
|
DEBUG_PRINTF("%s max char width is %d -- * %d = area %d\n", fname, ascii_char_maxwidth[i], ascii_bitmap[i]->h, area);
|
||||||
|
|
||||||
for (j = 0; j < num_chars; j++)
|
for (j = 0; j < num_chars; j++)
|
||||||
{
|
{
|
||||||
|
|
@ -213,14 +230,40 @@ int ascii_init(magic_api * api, Uint8 disabled_features ATTRIBUTE_UNUSED, Uint8
|
||||||
pixel = api->getpixel(ascii_bitmap[i], x, y);
|
pixel = api->getpixel(ascii_bitmap[i], x, y);
|
||||||
SDL_GetRGB(pixel, ascii_bitmap[i]->format, &r, &g, &b);
|
SDL_GetRGB(pixel, ascii_bitmap[i]->format, &r, &g, &b);
|
||||||
|
|
||||||
// printf("%3d ", (r + g + b) / 3);
|
DEBUG_PRINTF("%3d (%3d) ", (r + g + b) / 3, get_bright(api, r, g, b));
|
||||||
bright += ((r + g + b) / 3);
|
bright += get_bright(api, r, g, b);
|
||||||
}
|
}
|
||||||
// printf("\n");
|
DEBUG_PRINTF("\n");
|
||||||
}
|
}
|
||||||
// printf("char %d brightness = %d\n", j, bright / area);
|
DEBUG_PRINTF("char %3d brightness = %3d before padding -- ", j, bright / area);
|
||||||
|
w = ascii_char_maxwidth[i] - (ascii_char_x[i][j + 1] - ascii_char_x[i][j]) - 2; /* don't let padding affect _too_ much */
|
||||||
|
if (w >= 1)
|
||||||
|
bright += (clear_brightness * ascii_bitmap[i]->h * w);
|
||||||
|
DEBUG_PRINTF("%3d after padding %d width\n", bright / area, w);
|
||||||
ascii_char_brightness[i][j] = bright / area;
|
ascii_char_brightness[i][j] = bright / area;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stretch the brightnesses, so we cover more of 0->255 */
|
||||||
|
min_bright = 255;
|
||||||
|
max_bright = 0;
|
||||||
|
for (j = 0; j < num_chars; j++)
|
||||||
|
{
|
||||||
|
if (ascii_char_brightness[i][j] > max_bright)
|
||||||
|
max_bright = ascii_char_brightness[i][j];
|
||||||
|
if (ascii_char_brightness[i][j] < max_bright)
|
||||||
|
min_bright = ascii_char_brightness[i][j];
|
||||||
|
}
|
||||||
|
DEBUG_PRINTF("brightnesses between %d and %d\n", min_bright, max_bright);
|
||||||
|
|
||||||
|
/* https://rosettacode.org/wiki/Map_range#C */
|
||||||
|
#define map_range(a1,a2,b1,b2,s) (b1 + (s-a1)*(b2-b1)/(a2-a1))
|
||||||
|
|
||||||
|
for (j = 0; j < num_chars; j++)
|
||||||
|
{
|
||||||
|
DEBUG_PRINTF("mapping %3d -> ", ascii_char_brightness[i][j]);
|
||||||
|
ascii_char_brightness[i][j] = map_range(min_bright, max_bright, 0, 255, ascii_char_brightness[i][j]);
|
||||||
|
DEBUG_PRINTF("%3d\n", ascii_char_brightness[i][j]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
|
|
@ -246,7 +289,7 @@ char *ascii_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
|
||||||
{
|
{
|
||||||
char tmp[1024];
|
char tmp[1024];
|
||||||
|
|
||||||
snprintf(tmp, sizeof(tmp), gettext("ASCII %s"), ascii_tool_names[which]);
|
snprintf(tmp, sizeof(tmp), gettext("ASCII %s"), gettext(ascii_tool_names[which]));
|
||||||
return(strdup(tmp));
|
return(strdup(tmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -373,8 +416,10 @@ void ascii_set_size(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED
|
||||||
void do_ascii_effect(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
|
void do_ascii_effect(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y)
|
||||||
{
|
{
|
||||||
magic_api *api = (magic_api *) ptr;
|
magic_api *api = (magic_api *) ptr;
|
||||||
int w, h, n;
|
int w, h, n, xx, yy, brightness;
|
||||||
|
Uint8 r, g, b;
|
||||||
Uint32 clear_pixel;
|
Uint32 clear_pixel;
|
||||||
|
Uint8 clear_brightness;
|
||||||
SDL_Rect src, dest;
|
SDL_Rect src, dest;
|
||||||
|
|
||||||
w = ascii_char_maxwidth[which];
|
w = ascii_char_maxwidth[which];
|
||||||
|
|
@ -386,6 +431,8 @@ void do_ascii_effect(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * l
|
||||||
if (!api->touched(x, y))
|
if (!api->touched(x, y))
|
||||||
{
|
{
|
||||||
clear_pixel = api->getpixel(ascii_bitmap[which], 0, 0);
|
clear_pixel = api->getpixel(ascii_bitmap[which], 0, 0);
|
||||||
|
SDL_GetRGB(clear_pixel, ascii_bitmap[which]->format, &r, &g, &b);
|
||||||
|
clear_brightness = ((r + g + b) / 3.0);
|
||||||
|
|
||||||
dest.x = x;
|
dest.x = x;
|
||||||
dest.y = y;
|
dest.y = y;
|
||||||
|
|
@ -394,7 +441,22 @@ void do_ascii_effect(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * l
|
||||||
|
|
||||||
SDL_FillRect(canvas, &dest, clear_pixel);
|
SDL_FillRect(canvas, &dest, clear_pixel);
|
||||||
|
|
||||||
n = rand() % ascii_num_chars[which];
|
brightness = 0;
|
||||||
|
for (yy = y; yy < y + h; yy++)
|
||||||
|
{
|
||||||
|
for (xx = x; xx < x + w; xx++)
|
||||||
|
{
|
||||||
|
SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b);
|
||||||
|
brightness += get_bright(api, r, g, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
brightness = brightness / (w * h);
|
||||||
|
|
||||||
|
/* FIXME: Increase contrast */
|
||||||
|
|
||||||
|
if (brightness != clear_brightness)
|
||||||
|
{
|
||||||
|
n = get_best_char(which, brightness);
|
||||||
src.x = ascii_char_x[which][n];
|
src.x = ascii_char_x[which][n];
|
||||||
src.y = 0;
|
src.y = 0;
|
||||||
src.w = ascii_char_x[which][n + 1] - ascii_char_x[which][n];
|
src.w = ascii_char_x[which][n + 1] - ascii_char_x[which][n];
|
||||||
|
|
@ -405,4 +467,53 @@ void do_ascii_effect(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * l
|
||||||
|
|
||||||
SDL_BlitSurface(ascii_bitmap[which], &src, canvas, &dest);
|
SDL_BlitSurface(ascii_bitmap[which], &src, canvas, &dest);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_best_char(int which, int brightness)
|
||||||
|
{
|
||||||
|
int i, diff, best_idx, best_diff;
|
||||||
|
|
||||||
|
best_idx = -1;
|
||||||
|
best_diff = 255;
|
||||||
|
for (i = 0; i < ascii_num_chars[which]; i++)
|
||||||
|
{
|
||||||
|
diff = abs(ascii_char_brightness[which][i] - brightness);
|
||||||
|
|
||||||
|
if (diff == best_diff)
|
||||||
|
{
|
||||||
|
if (rand() % 10 <= 3)
|
||||||
|
best_idx = 1;
|
||||||
|
}
|
||||||
|
else if (diff < best_diff)
|
||||||
|
{
|
||||||
|
best_diff = diff;
|
||||||
|
best_idx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (best_idx == -1)
|
||||||
|
{
|
||||||
|
/* Shouldn't happen, but just in case */
|
||||||
|
best_idx = rand() % ascii_num_chars[which];
|
||||||
|
printf("!?\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_PRINTF("best for brightness %d is %d (brightness %d)\n",
|
||||||
|
brightness, best_idx, ascii_char_brightness[which][best_idx]);
|
||||||
|
|
||||||
|
return best_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_bright(magic_api * api, int r, int g, int b)
|
||||||
|
{
|
||||||
|
float fr, fg, fb, y;
|
||||||
|
|
||||||
|
fr = api->sRGB_to_linear(r);
|
||||||
|
fg = api->sRGB_to_linear(g);
|
||||||
|
fb = api->sRGB_to_linear(b);
|
||||||
|
|
||||||
|
y = (0.2126 * fr) + (0.7152 * fg) + (0.0722 * fb);
|
||||||
|
|
||||||
|
return (int) (y * 255);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,10 +47,10 @@
|
||||||
</screenshot>
|
</screenshot>
|
||||||
</screenshots>
|
</screenshots>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="0.9.34" date="2024-09-24">
|
<release version="0.9.34" date="2024-09-26">
|
||||||
<description>
|
<description>
|
||||||
<p>New Fill mode: "Eraser" flood fill.</p>
|
<p>New Fill mode: "Eraser" flood fill.</p>
|
||||||
<p>New Magic tools: "Comic dots", "Rotate", and various "Fractals".</p>
|
<p>New Magic tools: "Comic dots", "Rotate", "ASCII Computer", "ASCII Typewriter", and various "Fractals".</p>
|
||||||
<p>New brush: Fluff (gradient).</p>
|
<p>New brush: Fluff (gradient).</p>
|
||||||
</description>
|
</description>
|
||||||
</release>
|
</release>
|
||||||
|
|
|
||||||
|
|
@ -11918,7 +11918,7 @@ static SDL_Surface *thumbnail2(SDL_Surface * src, int max_x, int max_y, int keep
|
||||||
SDL_GetRGBA(getpixel(src, src_x, src_y), src->format, &r, &g, &b, &a);
|
SDL_GetRGBA(getpixel(src, src_x, src_y), src->format, &r, &g, &b, &a);
|
||||||
|
|
||||||
#ifdef GAMMA_CORRECTED_THUMBNAILS
|
#ifdef GAMMA_CORRECTED_THUMBNAILS
|
||||||
/* per: http://www.4p8.com/eric.brasseur/gamma.html */
|
/* per: http://www.ericbrasseur.org/gamma.html?i=1 */
|
||||||
|
|
||||||
tr = tr + sRGB_to_linear_table[r];
|
tr = tr + sRGB_to_linear_table[r];
|
||||||
tg = tg + sRGB_to_linear_table[g];
|
tg = tg + sRGB_to_linear_table[g];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue