From 03cdde257dbe183a0fe9375f710d4c0128a9574d Mon Sep 17 00:00:00 2001 From: William Kendrick Date: Sat, 21 Feb 2009 21:12:21 +0000 Subject: [PATCH] Added 3 'string art' tools. --- docs/CHANGES.txt | 7 +- magic/icons/string_art_angles.png | Bin 0 -> 1765 bytes magic/icons/string_art_full_by_offset.png | Bin 0 -> 4230 bytes magic/icons/string_art_triangles.png | Bin 0 -> 1935 bytes magic/src/string.c | 462 ++++++++++++++++++++++ 5 files changed, 468 insertions(+), 1 deletion(-) create mode 100644 magic/icons/string_art_angles.png create mode 100644 magic/icons/string_art_full_by_offset.png create mode 100644 magic/icons/string_art_triangles.png create mode 100644 magic/src/string.c diff --git a/docs/CHANGES.txt b/docs/CHANGES.txt index 77404746a..f21aeda91 100644 --- a/docs/CHANGES.txt +++ b/docs/CHANGES.txt @@ -8,7 +8,7 @@ http://www.tuxpaint.org/ $Id$ -2009.February.14 (0.9.21) +2009.February.21 (0.9.21) * New Starters: ------------- * Silver Frame @@ -49,6 +49,11 @@ $Id$ with modifications by Bill Kendrick and Pere Pujal i Carabantes + * String Edges - Draw string-like patters around the screen. + String Corner - Draw aligned string-like patterns. + String 'V' - Draw free-form string-like patterns. + By Pere Pujal i Carabantes + * Magic Tool Improvememnts: -------------------------- * Added "_switchin()" and "_switchout()" functions to Magic tool API, diff --git a/magic/icons/string_art_angles.png b/magic/icons/string_art_angles.png new file mode 100644 index 0000000000000000000000000000000000000000..91eb022d7321500162002cd851ddb63657d46b4f GIT binary patch literal 1765 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 Vk=D}W!p8sr002ovPDHLkV1g~Ei(>!) literal 0 HcmV?d00001 diff --git a/magic/src/string.c b/magic/src/string.c new file mode 100644 index 000000000..a7becd1b5 --- /dev/null +++ b/magic/src/string.c @@ -0,0 +1,462 @@ +#include "tp_magic_api.h" +#include "SDL_image.h" +#include "SDL_mixer.h" + + +Mix_Chunk * string_snd; +unsigned int img_w, img_h; +static Uint8 string_r, string_g, string_b; +static int string_ox, string_oy; +static int string_vertex_x, string_vertex_y, string_vertex_done, string_vertex_distance; +static SDL_Surface * canvas_backup; +enum string_tools{ + STRING_TOOL_FULL_BY_OFFSET, + STRING_TOOL_TRIANGLE, + STRING_TOOL_ANGLE, + STRING_NUMTOOLS}; + +// Custom function declarations + +void string_callback(void * ptr, int which_tool, + SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y); +void string_draw_triangle(magic_api * api, int which, + SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, + SDL_Rect * update_rect); +void string_draw_angle(magic_api * api, int which, + SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, + SDL_Rect * update_rect); +void string_draw_triangle_preview(magic_api * api, int which, + SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, + SDL_Rect * update_rect); +void string_draw_angle_preview(magic_api * api, int which, + SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, + SDL_Rect * update_rect); +void scale_xcoord(int * xcoord); +void scale_ycoord(int * ycoord); +void scale_coords(int * ox, int * oy, int * x, int * y); +void string_draw_wrapper(magic_api * api, int which, + SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, + SDL_Rect * update_rect); +void string_set_vertex(int x, int y); +void compute_middle( int start_point, int end_point, int vertex, int * middle); + + +// Prototypes for required functions + +void string_drag(magic_api * api, int which, SDL_Surface * canvas, + SDL_Surface * snapshot, int ox, int oy, int x, int y, + SDL_Rect * update_rect); + + +Uint32 string_api_version(void); +int string_modes(magic_api * api, int which); +void string_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); +int string_get_tool_count(magic_api * api); +SDL_Surface * string_get_icon(magic_api * api, int which); +char * string_get_name(magic_api * api, int which); +char * string_get_description(magic_api * api, int which, int mode); +int string_requires_colors(magic_api * api, int which); +void string_release(magic_api * api, int which, + SDL_Surface * canvas, SDL_Surface * snapshot, + int x, int y, SDL_Rect * update_rect); +int string_init(magic_api * api); +void string_shutdown(magic_api * api); +void string_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot); +void string_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * snapshot); +void string_click(magic_api * api, int which, int mode, + SDL_Surface * canvas, SDL_Surface * snapshot, + int x, int y, SDL_Rect * update_rect); + +// Required functions + +Uint32 string_api_version(void) +{ + return(TP_MAGIC_API_VERSION); +} + +int string_modes(__attribute__((unused)) magic_api * api, __attribute__((unused)) int which) +{ + return(MODE_PAINT); +} + +void string_set_color(__attribute__((unused)) magic_api * api, Uint8 r, Uint8 g, Uint8 b) +{ + string_r=r; + string_g=g; + string_b=b; +} + + + +int string_get_tool_count(__attribute__((unused)) magic_api * api) +{ + return STRING_NUMTOOLS; +} + +SDL_Surface * string_get_icon(magic_api * api, int which) +{ + char fname[1024]; + switch (which) + { + case STRING_TOOL_FULL_BY_OFFSET: + snprintf(fname, sizeof(fname), "%s/images/magic/string_art_full_by_offset.png", api->data_directory); + break; + case STRING_TOOL_TRIANGLE: + snprintf(fname, sizeof(fname), "%s/images/magic/string_art_triangles.png", api->data_directory); + break; + case STRING_TOOL_ANGLE: + snprintf(fname, sizeof(fname), "%s/images/magic/string_art_angles.png", api->data_directory); + break; + } + + return(IMG_Load(fname)); +} + + +char * string_get_name(__attribute__((unused)) magic_api * api, __attribute__((unused)) int which) +{ + switch (which) + { + case STRING_TOOL_FULL_BY_OFFSET: + return strdup(gettext_noop("String edges")); + break; + case STRING_TOOL_TRIANGLE: + return strdup(gettext_noop("String corner")); + break; + default: + return strdup(gettext_noop("String 'V'")); + } +} + +char * string_get_description(__attribute__((unused)) magic_api * api, int which, __attribute__((unused)) int mode) { + switch (which) + { + case STRING_TOOL_FULL_BY_OFFSET: + return strdup(gettext_noop("Click and drag to draw string art. Drag top-bottom to draw less or more lines, to the center to approach the lines to center.")); + break; + case STRING_TOOL_TRIANGLE: + return strdup(gettext_noop("Click and drag to draw string art aligned to the edges.")); + break; + default: + return strdup(gettext_noop("Draw string art with free angles. Click and drag a V: drag to the vertex, drag backwards a little to the start, then drag to the end.")); + } +} + +int string_requires_colors(__attribute__((unused)) magic_api * api, __attribute__((unused)) int which) { return 1;} + +void string_release(magic_api * api, int which, + SDL_Surface * canvas, SDL_Surface * snapshot, + int x, int y, SDL_Rect * update_rect) +{ + int dx, dy; + if (which==STRING_TOOL_TRIANGLE) + string_draw_triangle((void *) api, which, canvas, snapshot, string_ox, string_oy, x, y, update_rect); + if (which==STRING_TOOL_ANGLE) + { + if(!string_vertex_done) // maybe we face small children, draw square angles aligned to the drag + { + dx=string_ox - x; + dy=string_oy - y; + y=y + dx; + x=x - dy; + } + string_draw_angle((void *) api, which, canvas, snapshot, string_ox, string_oy, x, y, update_rect); + } + // no sound at the moment + // api->playsound(string_snd, (x * 255) / canvas->w, 255); +} + +int string_init(__attribute__((unused)) magic_api * api) +{ + return(1); +} + +void string_shutdown(__attribute__((unused)) magic_api * api) +{ + if (canvas_backup) + SDL_FreeSurface(canvas_backup); +} + +void string_switchin(__attribute__((unused)) magic_api * api, __attribute__((unused)) int which, __attribute__((unused)) int mode, SDL_Surface * canvas, __attribute__((unused)) SDL_Surface * snapshot) +{ + canvas_backup=SDL_CreateRGBSurface(SDL_ANYFORMAT, canvas->w, canvas->h, canvas->format->BitsPerPixel, + canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask); +} + +void string_switchout(__attribute__((unused)) magic_api * api, __attribute__((unused)) int which, __attribute__((unused)) int mode, __attribute__((unused)) SDL_Surface * canvas, __attribute__((unused)) SDL_Surface * snapshot) +{ + SDL_FreeSurface(canvas_backup); + canvas_backup=0; +} + +// Interactivity functions + + +void string_callback(void * ptr,__attribute__((unused)) int which, + SDL_Surface * canvas,__attribute__((unused)) SDL_Surface * snapshot, int x, int y) +{ + magic_api * api = (magic_api *) ptr; + api->putpixel(canvas, x, y, SDL_MapRGBA(canvas->format, string_r, string_g, string_b,255)); +} + + +void string_click(magic_api * api, int which,__attribute__((unused)) int mode, + SDL_Surface * canvas, SDL_Surface * snapshot, + int x, int y, SDL_Rect * update_rect) +{ + SDL_BlitSurface(canvas, NULL, canvas_backup, NULL); + + string_ox=x; + string_oy=y; + string_vertex_distance=0; + string_vertex_done=0; + string_drag(api, which, canvas, snapshot, x, y, x, y, update_rect); +} + +static void string_draw_full_by_offset(void * ptr, __attribute__((unused)) int which, SDL_Surface * canvas, __attribute__((unused)) SDL_Surface * snapshot, + int x, int y, SDL_Rect * update_rect) +{ + magic_api * api = (magic_api *) ptr; + int u; + int i; + int o; //offset + // int n=y/5; + int ** a; + float step_w, step_h, aux; + int side=(int)(y/3); + + SDL_BlitSurface(snapshot,0,canvas,0); + + if (side<3) side=3; + + o=(int)(side*4*x/canvas->w); + step_w=canvas->w/(float)side; + step_h=canvas->h/(float)side; + + a=malloc(sizeof(int*)*side*4*2); + + for (i=0;ih; + } + else + if (i<(int)(side*3)) + { + a[i][0]= canvas->w; + a[i][1]= (int)(canvas->h - (float)((i%side)*step_h)); + } + else + if (i<(int)(side*4)) + { + a[i][0]=(int)( canvas->w-((float)((i%side)*step_w))); + a[i][1]= 0; + } + } + + + for (i=0;iline((void *) api, which, canvas, snapshot,a[i][0],a[i][1],a[u][0],a[u][1],1, string_callback); + } + + for (i=0;ix=0; + update_rect->y=0; + update_rect->w=canvas->w; + update_rect->h=canvas->h; +} + +void scale_xcoord(int * xcoord) +{ + if (*xcoord < string_ox) *xcoord=string_ox-(string_ox - *xcoord)*4; + else *xcoord=string_ox+(*xcoord-string_ox)*4; +} + +void scale_ycoord(int * ycoord) +{ + if (*ycoord < string_oy) *ycoord=string_oy-(string_oy - *ycoord)*4; + else *ycoord=string_oy+(*ycoord-string_oy)*4; +} + +void scale_coords(int * ox, int * oy, int * x, int * y) +{ + scale_xcoord(ox); + scale_xcoord(x); + scale_ycoord(oy); + scale_ycoord(y); +} + +void compute_middle( int start_point, int end_point, int vertex, int * middle) +{ + *middle=min(start_point,end_point)+(max(start_point,end_point)-min(start_point,end_point))/2; + *middle=min(*middle,vertex)+(max(*middle,vertex)-min(*middle,vertex))/2; +} + +void string_draw_triangle_preview(magic_api * api, int which, + SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, + SDL_Rect * update_rect) +{ + scale_coords(&ox, &oy,&x, &y); + int middle_x, middle_y; + int w, h; + w=max(string_ox,x)-min(string_ox,x); + h=max(string_oy,y)-min(string_oy,y); + + /* + This is enouth if you move the mouse slowly, but if you move the mouse fast, + there are rests of old previews left around. + update_rect->w=max(max(string_ox,x),max(ox,x))-min(min(string_ox,x),min(ox,x)) +80; + update_rect->h=max(max(string_oy,y),max(oy,y))-min(min(string_oy,y),min(oy,y)) +80; + update_rect->x=min(string_ox,x) -40; + update_rect->y=min(string_oy,y) -40; + */ + update_rect->x=0; + update_rect->y=0; + update_rect->w=canvas->w; + update_rect->h=canvas->h; + SDL_BlitSurface(canvas_backup,update_rect,canvas,update_rect); + + compute_middle(x, string_ox, string_ox, &middle_x); + compute_middle(y, string_oy, string_oy, &middle_y); + + api->line((void *) api, which, canvas, snapshot, string_ox,string_oy, string_ox , y,1, string_callback); + api->line((void *) api, which, canvas, snapshot, string_ox,string_oy, x , string_oy,1, string_callback); + api->line((void *) api, which, canvas, snapshot, middle_x,middle_y, x , string_oy,1, string_callback); + api->line((void *) api, which, canvas, snapshot, string_ox,y, middle_x , middle_y,1, string_callback); +} + +void string_draw_angle_preview(magic_api * api, int which, + SDL_Surface * canvas, SDL_Surface * snapshot, __attribute__((unused)) int ox, __attribute__ ((unused)) int oy, int x, int y, + SDL_Rect * update_rect) +{ + int w, h; + int middle_x, middle_y; + int dx, dy; + w=max(string_ox,x)-min(string_ox,x); + h=max(string_oy,y)-min(string_oy,y); + + update_rect->x=0; + update_rect->y=0; + update_rect->w=canvas->w; + update_rect->h=canvas->h; + SDL_BlitSurface(canvas_backup,update_rect,canvas,update_rect); + + api->line((void *) api, which, canvas, snapshot, string_ox,string_oy, string_vertex_x , string_vertex_y,1, string_callback); + if(!string_vertex_done) + { + // if(!string_vertex_done) // maybe we face small children, draw square angles aligned to the drag + //{ + dx=string_ox - x; + dy=string_oy - y; + y=y + dx; + x=x - dy; + } + + compute_middle(string_ox, x, string_vertex_x, &middle_x); + compute_middle(string_oy, y, string_vertex_y, &middle_y); + + api->line((void *) api, which, canvas, snapshot, string_vertex_x,string_vertex_y, x , y,1, string_callback); + api->line((void *) api, which, canvas, snapshot, string_ox,string_oy, middle_x , middle_y,1, string_callback); + api->line((void *) api, which, canvas, snapshot, x, y, middle_x , middle_y,1, string_callback); + +} + +void string_draw_angle(magic_api * api, __attribute__((unused)) int which, + SDL_Surface * canvas, __attribute__((unused))SDL_Surface * snapshot, __attribute__ ((unused)) int ox, __attribute__ ((unused)) int oy, int x, int y, + SDL_Rect * update_rect) +{ + float first_arm_step_x, first_arm_step_y, second_arm_step_x, second_arm_step_y; + int i; + int max_wh , steps; + int max_separation=10; + + update_rect->x=min(min(string_ox,string_vertex_x),x); + update_rect->y=min(min(string_oy,string_vertex_y),y); + update_rect->w=max(max(string_ox,string_vertex_x),x)-update_rect->x; + update_rect->h=max(max(string_oy,string_vertex_y),y)-update_rect->y; + SDL_BlitSurface(canvas_backup,update_rect,canvas,update_rect); + + max_wh= max( max(max(string_ox,string_vertex_x),x)- min(min(string_vertex_x , x),string_ox) , max(max(string_oy , string_vertex_y),y)- min(min(string_vertex_y ,y),string_oy)); + + steps=max_wh/max_separation; + first_arm_step_x=(float)(string_ox-string_vertex_x)/(float)steps; + first_arm_step_y=(float)(string_oy-string_vertex_y)/(float)steps; + second_arm_step_x=(float)(string_vertex_x-x)/(float)steps; + second_arm_step_y=(float)(string_vertex_y-y)/(float)steps; + + for (i=0;i<=steps;i++) + { + api->line((void *) api, 0, canvas, snapshot, string_ox-first_arm_step_x*i,string_oy-first_arm_step_y*i, string_vertex_x-second_arm_step_x*i,string_vertex_y-second_arm_step_y*i,1, string_callback); + } +} + +void string_draw_triangle(magic_api * api, __attribute__((unused)) int which, + SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, + SDL_Rect * update_rect) +{ + SDL_BlitSurface(canvas_backup,0,canvas,0); + scale_coords(&ox, &oy,&x, &y); + + string_vertex_x=string_ox; + string_vertex_y=string_oy; + string_ox=string_vertex_x; + string_oy=y; + y=string_vertex_y; + + string_draw_angle((void *) api, which, canvas, snapshot, string_ox, string_oy, x, y, update_rect); +} + +void string_draw_wrapper(magic_api * api, int which, + SDL_Surface * canvas, SDL_Surface * snapshot, int ox, int oy, int x, int y, + SDL_Rect * update_rect) +{ + if (which==STRING_TOOL_FULL_BY_OFFSET) + string_draw_full_by_offset((void *) api, which, canvas, snapshot, x, y, update_rect); + else if (which==STRING_TOOL_TRIANGLE) + string_draw_triangle_preview ((void *) api, which, canvas, snapshot, ox, oy, x, y, update_rect); + else if (which==STRING_TOOL_ANGLE) + string_draw_angle_preview ((void *) api, which, canvas, snapshot, ox, oy, x, y, update_rect); +} + +void string_set_vertex(int x, int y) +{ + int dx, dy; + if (string_vertex_done) return; + dx=max(string_ox,x)-min(string_ox,x); + dy=max(string_oy,y)-min(string_oy,y); + if(dx+dy>string_vertex_distance) + { + string_vertex_distance=dx+dy; + string_vertex_x=x; + string_vertex_y=y; + } + if(dx+dy+30w)&&(yh)&&(oxw)&&(oyh)&&((signed)x>0)&&((signed)y>0)&&((signed)ox>0)&&((signed)oy>0)) + { + string_set_vertex(x,y); + string_draw_wrapper((void *) api, which, canvas, snapshot,ox,oy, x, y, update_rect); + } +}