From 5d2dd927e4eae5d64f51c250e8762ff6fb1bc417 Mon Sep 17 00:00:00 2001 From: Yves Rizoud Date: Sun, 30 Jan 2011 00:03:38 +0000 Subject: [PATCH] Much work on color brushes (issue 362). You can rotate, resize, flip etc. without losing original palette. git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1701 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- src/brush.c | 77 ++++++++++++++++++++++++++++++++----------- src/brush.h | 2 ++ src/buttons.c | 38 +++++++++++---------- src/buttons_effects.c | 9 +++-- src/engine.c | 10 ++++-- src/factory.c | 20 +++++++++-- src/loadsave.c | 1 + src/misc.c | 2 +- 8 files changed, 114 insertions(+), 45 deletions(-) diff --git a/src/brush.c b/src/brush.c index 398cac01..0d34cc96 100644 --- a/src/brush.c +++ b/src/brush.c @@ -550,7 +550,6 @@ byte Realloc_brush(word new_brush_width, word new_brush_height, byte *new_brush, // All allocations successful: can replace globals Brush_width=new_brush_width; Brush_height=new_brush_height; - memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette)); Brush_original_back_color=Back_color; if (new_smear_brush) @@ -573,12 +572,6 @@ byte Realloc_brush(word new_brush_width, word new_brush_height, byte *new_brush, free(Brush); Brush=new_brush_remapped; } - if (new_brush_is_provided) - { - // Copy from Brush_original_pixels to Brush, using the last defined colmap. - Remap_general_lowlevel(Brush_colormap,Brush_original_pixels,Brush,Brush_width,Brush_height,Brush_width); - //memcpy(Brush, Brush_original_pixels,(long)Brush_width*Brush_height); - } return 0; } @@ -776,8 +769,10 @@ void Capture_brush(short start_x,short start_y,short end_x,short end_y,short cle } Update_part_of_screen(start_x,start_y,Brush_width,Brush_height); } - // Copy without remap - memcpy(Brush_original_pixels, Brush, (long)Brush_height*Brush_width); + // Grab palette + memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette)); + // Remap (no change) + Remap_brush(); // On centre la prise sur la brosse Brush_offset_X=(Brush_width>>1); @@ -799,8 +794,8 @@ void Rotate_90_deg(void) free(old_brush); - // Copy without remap - memcpy(Brush, Brush_original_pixels, (long)Brush_height*Brush_width); + // Remap according to the last used remap table + Remap_general_lowlevel(Brush_colormap,Brush_original_pixels,Brush,Brush_width,Brush_height,Brush_width); // On centre la prise sur la brosse Brush_offset_X=(Brush_width>>1); @@ -876,13 +871,16 @@ void Outline_brush(void) byte * old_brush; word old_width; word old_height; + int i; old_width=Brush_width; old_height=Brush_height; + SWAP_PBYTES(Brush, Brush_original_pixels); if(Realloc_brush(Brush_width+2, Brush_height+2, NULL, &old_brush)) { Error(0); + SWAP_PBYTES(Brush, Brush_original_pixels); return; } @@ -948,8 +946,12 @@ void Outline_brush(void) Pixel_in_brush(x_pos,y_pos,Fore_color); } } - // Copy without remap - memcpy(Brush_original_pixels, Brush, (long)Brush_height*Brush_width); + // Adopt the current palette. + memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette)); + memcpy(Brush_original_pixels, Brush, (long)Brush_width*Brush_height); + for (i=0; i<256; i++) + Brush_colormap[i]=i; + //-- // On recentre la prise sur la brosse Brush_offset_X=(Brush_width>>1); @@ -967,15 +969,18 @@ void Nibble_brush(void) byte * old_brush; word old_width; word old_height; + int i; if ( (Brush_width>2) && (Brush_height>2) ) { old_width=Brush_width; old_height=Brush_height; + SWAP_PBYTES(Brush, Brush_original_pixels); if (Realloc_brush(Brush_width-2, Brush_height-2, NULL, &old_brush)) { Error(0); + SWAP_PBYTES(Brush, Brush_original_pixels); return; } // On copie l'ancienne brosse dans la nouvelle @@ -1049,8 +1054,12 @@ void Nibble_brush(void) } free(old_brush); - // Copy without remap - memcpy(Brush_original_pixels, Brush, (long)Brush_height*Brush_width); + // Adopt the current palette. + memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette)); + memcpy(Brush_original_pixels, Brush, (long)Brush_width*Brush_height); + for (i=0; i<256; i++) + Brush_colormap[i]=i; + //-- // On recentre la prise sur la brosse Brush_offset_X=(Brush_width>>1); @@ -1150,8 +1159,10 @@ void Capture_brush_with_lasso(int vertices, short * points,short clear) if (clear) Pixel_in_current_screen(x_pos,y_pos,Back_color,0); } - // Copy without remap - memcpy(Brush_original_pixels, Brush, (long)Brush_height*Brush_width); + // Grab palette + memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette)); + // Remap (no change) + Remap_brush(); // On centre la prise sur la brosse Brush_offset_X=(Brush_width>>1); @@ -1192,7 +1203,7 @@ void Stretch_brush(short x1, short y1, short x2, short y2) return; } - Rescale(Brush, Brush_width, Brush_height, new_brush, new_brush_width, new_brush_height, x2>1); Brush_offset_Y=(Brush_height>>1); @@ -1477,6 +1490,8 @@ void Distort_brush(short x1, short y1, short x2, short y2, short x3, short y3, s Error(0); return; } + // Remap according to the last used remap table + Remap_general_lowlevel(Brush_colormap,Brush_original_pixels,Brush,Brush_width,Brush_height,Brush_width); // Re-center brush handle Brush_offset_X=(Brush_width>>1); @@ -1701,7 +1716,7 @@ void Compute_quad_texture(int x1,int y1,int xt1,int yt1, xt=Round((float)(ScanY_Xt[0][y])+(temp*(ScanY_Xt[1][y]-ScanY_Xt[0][y]))); yt=Round((float)(ScanY_Yt[0][y])+(temp*(ScanY_Yt[1][y]-ScanY_Yt[0][y]))); if (xt>=0 && yt>=0) - buffer[x+(y*width)]=Read_pixel_from_brush(xt,yt); + buffer[x+(y*width)]=*(Brush_original_pixels + yt * Brush_width + xt); } for (; x>1); @@ -1900,3 +1917,25 @@ void Rotate_brush_preview(float angle) end_y=Max(Max(y1,y2),Max(y3,y4)); Update_part_of_screen(start_x,start_y,end_x-start_x+1,end_y-start_y+1); } +/* +/// Sets brush's original palette and color mapping. +void Brush_set_palette(T_Palette *palette) +{ + int i; + byte need_remap; + + need_remap=0; + + memcpy(Brush_original_palette,palette,sizeof(T_Palette)); + for (i=0;i<256;i++) + { + if (Brush_original_palette[i].R!=Main_palette[i].R + || Brush_original_palette[i].G!=Main_palette[i].G + || Brush_original_palette[i].B!=Main_palette[i].B) + { + need_remap=1; + } + } + +} +*/ \ No newline at end of file diff --git a/src/brush.h b/src/brush.h index bbd2a3c4..9682b1fe 100644 --- a/src/brush.h +++ b/src/brush.h @@ -122,6 +122,8 @@ void Capture_brush_with_lasso(int vertices, short * points,short clear); /// (after transferring pixels to Brush, usually). byte Realloc_brush(word new_brush_width, word new_brush_height, byte *new_brush, byte **old_brush); +/// Sets brush's original palette and color mapping. +void Brush_set_palette(T_Palette *palette); #endif diff --git a/src/buttons.c b/src/buttons.c index 731937a0..fba75319 100644 --- a/src/buttons.c +++ b/src/buttons.c @@ -3098,7 +3098,6 @@ void Load_picture(byte image) // Image=0 => On charge/sauve une brosse { byte confirm; - byte use_brush_palette = 0; byte old_cursor_shape; int new_mode; T_IO_Context context; @@ -3126,8 +3125,6 @@ void Load_picture(byte image) if (Main_image_is_modified) confirm=Confirmation_box("Discard unsaved changes?"); } - else - use_brush_palette=Confirmation_box("Use the palette of the brush?"); } // confirm is modified inside the first if, that's why we check it @@ -3149,9 +3146,6 @@ void Load_picture(byte image) if (!image) { - //if (!use_brush_palette) - // memcpy(Main_palette,initial_palette,sizeof(T_Palette)); - if (File_error==3) // Memory allocation error when loading brush { // Nothing to do here. @@ -3926,10 +3920,14 @@ void Button_Brush_FX(void) switch (clicked_button) { case 2 : // Flip X - Flip_X_lowlevel(Brush, Brush_width, Brush_height); + Flip_X_lowlevel(Brush_original_pixels, Brush_width, Brush_height); + // Remap according to the last used remap table + Remap_general_lowlevel(Brush_colormap,Brush_original_pixels,Brush,Brush_width,Brush_height,Brush_width); break; case 3 : // Flip Y - Flip_Y_lowlevel(Brush, Brush_width, Brush_height); + Flip_Y_lowlevel(Brush_original_pixels, Brush_width, Brush_height); + // Remap according to the last used remap table + Remap_general_lowlevel(Brush_colormap,Brush_original_pixels,Brush,Brush_width,Brush_height,Brush_width); break; case 4 : // 90° Rotation Rotate_90_deg(); @@ -4988,14 +4986,14 @@ void Button_Text(void) Display_cursor(); Error(0); } + // Grab palette + memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette)); + // Remap (no change) + Remap_brush(); Brush_offset_X=Brush_width>>1; Brush_offset_Y=Brush_height>>1; - // TODO: Import original palette - // Remap to current screen palette - Remap_brush(); - // Fermeture Close_window(); Unselect_button(BUTTON_TEXT); @@ -5144,19 +5142,19 @@ void Store_brush(int index) Brush_container[index].Width=Brush_width; Brush_container[index].Height=Brush_height; - memcpy(Brush_container[index].Brush, Brush,Brush_height*Brush_width); + memcpy(Brush_container[index].Brush, Brush_original_pixels,Brush_height*Brush_width); // Scale for preview if (Brush_width>BRUSH_CONTAINER_PREVIEW_WIDTH || Brush_height>BRUSH_CONTAINER_PREVIEW_HEIGHT) { // Scale - Rescale(Brush, Brush_width, Brush_height, (byte *)(Brush_container[index].Thumbnail), BRUSH_CONTAINER_PREVIEW_WIDTH, BRUSH_CONTAINER_PREVIEW_HEIGHT, 0, 0); + Rescale(Brush_original_pixels, Brush_width, Brush_height, (byte *)(Brush_container[index].Thumbnail), BRUSH_CONTAINER_PREVIEW_WIDTH, BRUSH_CONTAINER_PREVIEW_HEIGHT, 0, 0); } else { // Direct copy - Copy_part_of_image_to_another(Brush, 0,0,Brush_width, Brush_height,Brush_width,(byte *)(Brush_container[index].Thumbnail),0,0,BRUSH_CONTAINER_PREVIEW_WIDTH); + Copy_part_of_image_to_another(Brush_original_pixels, 0,0,Brush_width, Brush_height,Brush_width,(byte *)(Brush_container[index].Thumbnail),0,0,BRUSH_CONTAINER_PREVIEW_WIDTH); } } else @@ -5286,10 +5284,14 @@ byte Restore_brush(int index) Paintbrush_shape=shape; if (!Realloc_brush(Brush_container[index].Width,Brush_container[index].Height,NULL,NULL)) { - // Realloc sets Brush_width and Brush_height to new size. + // Recover pixels memcpy(Brush_original_pixels, Brush_container[index].Brush, (long)Brush_height*Brush_width); - // Copy without remap - memcpy(Brush, Brush_original_pixels, (long)Brush_height*Brush_width); + // Grab palette (TODO: get saved palette from brush container) + memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette)); + // Remap (no change) + Remap_brush(); + + Brush_offset_X=Brush_width>>1; Brush_offset_Y=Brush_height>>1; } diff --git a/src/buttons_effects.c b/src/buttons_effects.c index 2ab0bfdc..6f621a63 100644 --- a/src/buttons_effects.c +++ b/src/buttons_effects.c @@ -1080,10 +1080,13 @@ void Button_Sieve_menu(void) for (y_pos=0; y_pos>1); Brush_offset_Y=(Brush_height>>1); diff --git a/src/engine.c b/src/engine.c index 8db0ac50..1e2ad64a 100644 --- a/src/engine.c +++ b/src/engine.c @@ -894,13 +894,17 @@ void Main_handler(void) break; case SPECIAL_FLIP_X : // Flip X Hide_cursor(); - Flip_X_lowlevel(Brush, Brush_width, Brush_height); + Flip_X_lowlevel(Brush_original_pixels, Brush_width, Brush_height); + // Remap according to the last used remap table + Remap_general_lowlevel(Brush_colormap,Brush_original_pixels,Brush,Brush_width,Brush_height,Brush_width); Display_cursor(); action++; break; case SPECIAL_FLIP_Y : // Flip Y Hide_cursor(); - Flip_Y_lowlevel(Brush, Brush_width, Brush_height); + Flip_Y_lowlevel(Brush_original_pixels, Brush_width, Brush_height); + // Remap according to the last used remap table + Remap_general_lowlevel(Brush_colormap,Brush_original_pixels,Brush,Brush_width,Brush_height,Brush_width); Display_cursor(); action++; break; @@ -913,6 +917,8 @@ void Main_handler(void) case SPECIAL_ROTATE_180 : // 180° brush rotation Hide_cursor(); Rotate_180_deg_lowlevel(Brush, Brush_width, Brush_height); + // Remap according to the last used remap table + Remap_general_lowlevel(Brush_colormap,Brush_original_pixels,Brush,Brush_width,Brush_height,Brush_width); Brush_offset_X=(Brush_width>>1); Brush_offset_Y=(Brush_height>>1); Display_cursor(); diff --git a/src/factory.c b/src/factory.c index 1a4bce26..2b270a54 100644 --- a/src/factory.c +++ b/src/factory.c @@ -168,7 +168,11 @@ int L_SetBrushSize(lua_State* L) Brush_was_altered=1; // Fill with Back_color memset(Brush_original_pixels,Back_color,(long)Brush_width*Brush_height); - memset(Brush,Back_color,(long)Brush_width*Brush_height); + // Grab palette + memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette)); + // Remap (no change) + Remap_brush(); + // Center the handle Brush_offset_X=(Brush_width>>1); Brush_offset_Y=(Brush_height>>1); @@ -200,7 +204,19 @@ int L_PutBrushPixel(lua_State* L) LUA_ARG_NUMBER(2, "putbrushpixel", y, INT_MIN, INT_MAX); LUA_ARG_NUMBER(3, "putbrushpixel", c, INT_MIN, INT_MAX); - Brush_was_altered=1; + if (!Brush_was_altered) + { + int i; + + // First time writing in brush: + // Adopt the current palette. + memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette)); + memcpy(Brush_original_pixels, Brush, Brush_width*Brush_height); + for (i=0; i<256; i++) + Brush_colormap[i]=i; + //-- + Brush_was_altered=1; + } if (x<0 || y<0 || x>=Brush_width || y>=Brush_height) ; diff --git a/src/loadsave.c b/src/loadsave.c index 1867fe04..2c53f7c2 100644 --- a/src/loadsave.c +++ b/src/loadsave.c @@ -781,6 +781,7 @@ void Load_image(T_IO_Context *context) free(context->Buffer_image); } memcpy(Brush_original_palette, context->Palette, sizeof(T_Palette)); + Remap_brush(); context->Buffer_image = NULL; } diff --git a/src/misc.c b/src/misc.c index 6644c1fa..442621e1 100644 --- a/src/misc.c +++ b/src/misc.c @@ -362,7 +362,7 @@ void Remap_general_lowlevel(byte * conversion_table,byte * in_buffer, byte *out_ void Copy_image_to_brush(short start_x,short start_y,short Brush_width,short Brush_height,word image_width) { byte* src=start_y*image_width+start_x+Main_backups->Pages->Image[Main_current_layer]; //Adr départ image (ESI) - byte* dest=Brush; //Adr dest brosse (EDI) + byte* dest=Brush_original_pixels; //Adr dest brosse (EDI) int dx; for (dx=Brush_height;dx!=0;dx--)