diff --git a/magic/src/blackAndWhite.c b/magic/src/blackAndWhite.c index 4d5769e09..d7e65e728 100644 --- a/magic/src/blackAndWhite.c +++ b/magic/src/blackAndWhite.c @@ -48,6 +48,11 @@ enum { bandw_NUM_TOOLS }; +int bandw_min = INT_MAX; +int bandw_max = 0; + +const int bandw_RADIUS =16; + static Mix_Chunk * bandw_snd_effect[bandw_NUM_TOOLS]; const char * bandw_snd_filenames[bandw_NUM_TOOLS] = { @@ -62,9 +67,11 @@ const char * bandw_names[bandw_NUM_TOOLS] = { gettext_noop("Black & White"), gettext_noop("Threshold") }; -const char * bandw_descs[bandw_NUM_TOOLS] = { - gettext_noop("Click to convert the image to greyscale."), - gettext_noop("Click to threshold the image into black and white regions.") +const char * bandw_descs[bandw_NUM_TOOLS][2] = { + {gettext_noop("Click and move the mouse around convert the image to greyscale."), + gettext_noop("Click to convert the image to greyscale."),}, + {gettext_noop("Click and move the mouse around to threshold the image into black and white regions."), + gettext_noop("Click to threshold the image into black and white regions.")} }; Uint32 blackAndWhite_api_version(void) { return(TP_MAGIC_API_VERSION); } @@ -99,7 +106,7 @@ char * blackAndWhite_get_name(magic_api * api, int which){ // Return our descriptions, localized: char * blackAndWhite_get_description(magic_api * api, int which, int mode){ - return(strdup(gettext(bandw_descs[which]))); + return(strdup(gettext(bandw_descs[which][mode-1]))); } //Calculates the grey scale value for a rgb pixel @@ -107,72 +114,89 @@ static int blackAndWhite_grey(Uint8 r1,Uint8 g1,Uint8 b1){ return 0.3*r1+.59*g1+0.11*b1; } +static void do_blackAndWhite_pixel(void * ptr, int which, + SDL_Surface * canvas, SDL_Surface * last, + int x, int y){ + magic_api * api = (magic_api *) ptr; + Uint8 r1,g1,b1; + + SDL_GetRGB(api->getpixel(last, x, y), last->format, &r1, &g1, &b1); + int greyValue = blackAndWhite_grey(r1,g1,b1); + + if (which == TOOL_BANDW){ + api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, greyValue, greyValue, greyValue)); + }else{ + int thresholdValue = (bandw_max-bandw_min)/2; + if (greyValue < thresholdValue){ + api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 0, 0, 0)); + }else{ + api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 255, 255, 255)); + } + } +} + // Do the effect: -static void do_blackAndWhite(void * ptr,SDL_Surface * canvas, SDL_Surface * last, int which){ +static void do_blackAndWhite_full(void * ptr,SDL_Surface * canvas, SDL_Surface * last, int which){ magic_api * api = (magic_api *) ptr; int x,y; - Uint8 r1,g1,b1; - int min = INT_MAX; - int max = 0; - int thresholdValue; + for (y = 0; y < last->h; y++){ + for (x=0; x < last->w; x++){ + do_blackAndWhite_pixel(ptr, which, canvas, last, x, y); + } + } +} - for (y = 0; y < last->h; y++) - { - for (x=0; x < last->w; x++) - { - SDL_GetRGB(api->getpixel(last, x, y), last->format, &r1, &g1, &b1); - int greyValue = blackAndWhite_grey(r1,g1,b1); - if (which == TOOL_BANDW) - { - api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, greyValue, greyValue, greyValue)); - }else if(which == TOOL_THRESHOLD) - { - if (greyValuemax) - { - max=greyValue; - } - } - } - } - thresholdValue = (max-min)/2; - if (which == TOOL_THRESHOLD){ - for (y = 0; y < last->h; y++){ - for (x=0; x < last->w; x++){ - SDL_GetRGB(api->getpixel(last, x, y), last->format, &r1, &g1, &b1); - int greyValue = blackAndWhite_grey(r1,g1,b1); - if (greyValue < thresholdValue){ - api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 0, 0, 0)); - }else{ - api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 255, 255, 255)); - } - } - } - } +static void do_blackAndWhite_brush(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y){ + int xx, yy; + magic_api * api = (magic_api *) ptr; + + for (yy = y - bandw_RADIUS; yy < y + bandw_RADIUS; yy++) + { + for (xx = x - bandw_RADIUS; xx < x + bandw_RADIUS; xx++) + { + if (api->in_circle(xx - x, yy - y, bandw_RADIUS) && + !api->touched(xx, yy)) + { + do_blackAndWhite_pixel(api, which, canvas, last, xx, yy); + } + } + } } // Affect the canvas on drag: void blackAndWhite_drag(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect){ - // No-op + + api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_blackAndWhite_brush); + + api->playsound(bandw_snd_effect[which], (x * 255) / canvas->w, 255); + + if (ox > x) { int tmp = ox; ox = x; x = tmp; } + if (oy > y) { int tmp = oy; oy = y; y = tmp; } + + update_rect->x = ox - bandw_RADIUS; + update_rect->y = oy - bandw_RADIUS; + update_rect->w = (x + bandw_RADIUS) - update_rect->x; + update_rect->h = (y + bandw_RADIUS) - update_rect->y; } // Affect the canvas on click: void blackAndWhite_click(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect){ - update_rect->x = 0; - update_rect->y = 0; - update_rect->w = canvas->w; - update_rect->h = canvas->h; - do_blackAndWhite(api, canvas, last, which); - api->playsound(bandw_snd_effect[which], 128, 255); + if (mode == MODE_PAINT) + blackAndWhite_drag(api, which, canvas, last, x, y, x, y, update_rect); + else{ + update_rect->x = 0; + update_rect->y = 0; + update_rect->w = canvas->w; + update_rect->h = canvas->h; + do_blackAndWhite_full(api, canvas, last, which); + api->playsound(bandw_snd_effect[which], 128, 255); + } } // Affect the canvas on release: @@ -205,8 +229,23 @@ int blackAndWhite_requires_colors(magic_api * api, int which) return 0; } -void blackAndWhite_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas) -{ +void blackAndWhite_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas){ + + int x,y; + Uint8 r1,g1,b1; + + for (y = 0; y < canvas->h; y++){ + for (x=0; x < canvas->w; x++){ + SDL_GetRGB(api->getpixel(canvas, x, y), canvas->format, &r1, &g1, &b1); + int greyValue = blackAndWhite_grey(r1,g1,b1); + if (greyValuebandw_max){ + bandw_max=greyValue; + } + } + } } void blackAndWhite_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas) @@ -215,5 +254,5 @@ void blackAndWhite_switchout(magic_api * api, int which, int mode, SDL_Surface * int blackAndWhite_modes(magic_api * api, int which) { - return(MODE_FULLSCREEN); /* FIXME - Can also be turned into a painted effect */ + return(MODE_FULLSCREEN|MODE_PAINT); }