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
This commit is contained in:
Yves Rizoud 2011-01-30 00:03:38 +00:00
parent e01b310317
commit 5d2dd927e4
8 changed files with 114 additions and 45 deletions

View File

@ -550,7 +550,6 @@ byte Realloc_brush(word new_brush_width, word new_brush_height, byte *new_brush,
// All allocations successful: can replace globals // All allocations successful: can replace globals
Brush_width=new_brush_width; Brush_width=new_brush_width;
Brush_height=new_brush_height; Brush_height=new_brush_height;
memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette));
Brush_original_back_color=Back_color; Brush_original_back_color=Back_color;
if (new_smear_brush) if (new_smear_brush)
@ -573,12 +572,6 @@ byte Realloc_brush(word new_brush_width, word new_brush_height, byte *new_brush,
free(Brush); free(Brush);
Brush=new_brush_remapped; 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; 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); Update_part_of_screen(start_x,start_y,Brush_width,Brush_height);
} }
// Copy without remap // Grab palette
memcpy(Brush_original_pixels, Brush, (long)Brush_height*Brush_width); memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette));
// Remap (no change)
Remap_brush();
// On centre la prise sur la brosse // On centre la prise sur la brosse
Brush_offset_X=(Brush_width>>1); Brush_offset_X=(Brush_width>>1);
@ -799,8 +794,8 @@ void Rotate_90_deg(void)
free(old_brush); free(old_brush);
// Copy without remap // Remap according to the last used remap table
memcpy(Brush, Brush_original_pixels, (long)Brush_height*Brush_width); Remap_general_lowlevel(Brush_colormap,Brush_original_pixels,Brush,Brush_width,Brush_height,Brush_width);
// On centre la prise sur la brosse // On centre la prise sur la brosse
Brush_offset_X=(Brush_width>>1); Brush_offset_X=(Brush_width>>1);
@ -876,13 +871,16 @@ void Outline_brush(void)
byte * old_brush; byte * old_brush;
word old_width; word old_width;
word old_height; word old_height;
int i;
old_width=Brush_width; old_width=Brush_width;
old_height=Brush_height; old_height=Brush_height;
SWAP_PBYTES(Brush, Brush_original_pixels);
if(Realloc_brush(Brush_width+2, Brush_height+2, NULL, &old_brush)) if(Realloc_brush(Brush_width+2, Brush_height+2, NULL, &old_brush))
{ {
Error(0); Error(0);
SWAP_PBYTES(Brush, Brush_original_pixels);
return; return;
} }
@ -948,8 +946,12 @@ void Outline_brush(void)
Pixel_in_brush(x_pos,y_pos,Fore_color); Pixel_in_brush(x_pos,y_pos,Fore_color);
} }
} }
// Copy without remap // Adopt the current palette.
memcpy(Brush_original_pixels, Brush, (long)Brush_height*Brush_width); 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 // On recentre la prise sur la brosse
Brush_offset_X=(Brush_width>>1); Brush_offset_X=(Brush_width>>1);
@ -967,15 +969,18 @@ void Nibble_brush(void)
byte * old_brush; byte * old_brush;
word old_width; word old_width;
word old_height; word old_height;
int i;
if ( (Brush_width>2) && (Brush_height>2) ) if ( (Brush_width>2) && (Brush_height>2) )
{ {
old_width=Brush_width; old_width=Brush_width;
old_height=Brush_height; old_height=Brush_height;
SWAP_PBYTES(Brush, Brush_original_pixels);
if (Realloc_brush(Brush_width-2, Brush_height-2, NULL, &old_brush)) if (Realloc_brush(Brush_width-2, Brush_height-2, NULL, &old_brush))
{ {
Error(0); Error(0);
SWAP_PBYTES(Brush, Brush_original_pixels);
return; return;
} }
// On copie l'ancienne brosse dans la nouvelle // On copie l'ancienne brosse dans la nouvelle
@ -1049,8 +1054,12 @@ void Nibble_brush(void)
} }
free(old_brush); free(old_brush);
// Copy without remap // Adopt the current palette.
memcpy(Brush_original_pixels, Brush, (long)Brush_height*Brush_width); 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 // On recentre la prise sur la brosse
Brush_offset_X=(Brush_width>>1); Brush_offset_X=(Brush_width>>1);
@ -1150,8 +1159,10 @@ void Capture_brush_with_lasso(int vertices, short * points,short clear)
if (clear) if (clear)
Pixel_in_current_screen(x_pos,y_pos,Back_color,0); Pixel_in_current_screen(x_pos,y_pos,Back_color,0);
} }
// Copy without remap // Grab palette
memcpy(Brush_original_pixels, Brush, (long)Brush_height*Brush_width); memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette));
// Remap (no change)
Remap_brush();
// On centre la prise sur la brosse // On centre la prise sur la brosse
Brush_offset_X=(Brush_width>>1); Brush_offset_X=(Brush_width>>1);
@ -1192,7 +1203,7 @@ void Stretch_brush(short x1, short y1, short x2, short y2)
return; return;
} }
Rescale(Brush, Brush_width, Brush_height, new_brush, new_brush_width, new_brush_height, x2<x1, y2<y1); Rescale(Brush_original_pixels, Brush_width, Brush_height, new_brush, new_brush_width, new_brush_height, x2<x1, y2<y1);
if (Realloc_brush(new_brush_width, new_brush_height, new_brush, NULL)) if (Realloc_brush(new_brush_width, new_brush_height, new_brush, NULL))
{ {
@ -1200,6 +1211,8 @@ void Stretch_brush(short x1, short y1, short x2, short y2)
Error(0); Error(0);
return; return;
} }
// 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_X=(Brush_width>>1);
Brush_offset_Y=(Brush_height>>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); Error(0);
return; 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 // Re-center brush handle
Brush_offset_X=(Brush_width>>1); 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]))); 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]))); yt=Round((float)(ScanY_Yt[0][y])+(temp*(ScanY_Yt[1][y]-ScanY_Yt[0][y])));
if (xt>=0 && yt>=0) 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<width; x++) for (; x<width; x++)
buffer[x+(y*width)]=Back_color; buffer[x+(y*width)]=Back_color;
@ -1773,6 +1788,8 @@ void Rotate_brush(float angle)
free(new_brush); free(new_brush);
return; return;
} }
// Remap according to the last used remap table
Remap_general_lowlevel(Brush_colormap,Brush_original_pixels,Brush,Brush_width,Brush_height,Brush_width);
// Center offsets // Center offsets
Brush_offset_X=(Brush_width>>1); Brush_offset_X=(Brush_width>>1);
@ -1900,3 +1917,25 @@ void Rotate_brush_preview(float angle)
end_y=Max(Max(y1,y2),Max(y3,y4)); 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); 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;
}
}
}
*/

View File

@ -122,6 +122,8 @@ void Capture_brush_with_lasso(int vertices, short * points,short clear);
/// (after transferring pixels to Brush, usually). /// (after transferring pixels to Brush, usually).
byte Realloc_brush(word new_brush_width, word new_brush_height, byte *new_brush, byte **old_brush); 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 #endif

View File

@ -3098,7 +3098,6 @@ void Load_picture(byte image)
// Image=0 => On charge/sauve une brosse // Image=0 => On charge/sauve une brosse
{ {
byte confirm; byte confirm;
byte use_brush_palette = 0;
byte old_cursor_shape; byte old_cursor_shape;
int new_mode; int new_mode;
T_IO_Context context; T_IO_Context context;
@ -3126,8 +3125,6 @@ void Load_picture(byte image)
if (Main_image_is_modified) if (Main_image_is_modified)
confirm=Confirmation_box("Discard unsaved changes?"); 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 // 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 (!image)
{ {
//if (!use_brush_palette)
// memcpy(Main_palette,initial_palette,sizeof(T_Palette));
if (File_error==3) // Memory allocation error when loading brush if (File_error==3) // Memory allocation error when loading brush
{ {
// Nothing to do here. // Nothing to do here.
@ -3926,10 +3920,14 @@ void Button_Brush_FX(void)
switch (clicked_button) switch (clicked_button)
{ {
case 2 : // Flip X 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; break;
case 3 : // Flip Y 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; break;
case 4 : // 90° Rotation case 4 : // 90° Rotation
Rotate_90_deg(); Rotate_90_deg();
@ -4988,14 +4986,14 @@ void Button_Text(void)
Display_cursor(); Display_cursor();
Error(0); 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_X=Brush_width>>1;
Brush_offset_Y=Brush_height>>1; Brush_offset_Y=Brush_height>>1;
// TODO: Import original palette
// Remap to current screen palette
Remap_brush();
// Fermeture // Fermeture
Close_window(); Close_window();
Unselect_button(BUTTON_TEXT); Unselect_button(BUTTON_TEXT);
@ -5144,19 +5142,19 @@ void Store_brush(int index)
Brush_container[index].Width=Brush_width; Brush_container[index].Width=Brush_width;
Brush_container[index].Height=Brush_height; 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 // Scale for preview
if (Brush_width>BRUSH_CONTAINER_PREVIEW_WIDTH || if (Brush_width>BRUSH_CONTAINER_PREVIEW_WIDTH ||
Brush_height>BRUSH_CONTAINER_PREVIEW_HEIGHT) Brush_height>BRUSH_CONTAINER_PREVIEW_HEIGHT)
{ {
// Scale // 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 else
{ {
// Direct copy // 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 else
@ -5286,10 +5284,14 @@ byte Restore_brush(int index)
Paintbrush_shape=shape; Paintbrush_shape=shape;
if (!Realloc_brush(Brush_container[index].Width,Brush_container[index].Height,NULL,NULL)) 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); memcpy(Brush_original_pixels, Brush_container[index].Brush, (long)Brush_height*Brush_width);
// Copy without remap // Grab palette (TODO: get saved palette from brush container)
memcpy(Brush, Brush_original_pixels, (long)Brush_height*Brush_width); memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette));
// Remap (no change)
Remap_brush();
Brush_offset_X=Brush_width>>1; Brush_offset_X=Brush_width>>1;
Brush_offset_Y=Brush_height>>1; Brush_offset_Y=Brush_height>>1;
} }

View File

@ -1080,10 +1080,13 @@ void Button_Sieve_menu(void)
for (y_pos=0; y_pos<Sieve_height; y_pos++) for (y_pos=0; y_pos<Sieve_height; y_pos++)
for (x_pos=0; x_pos<Sieve_width; x_pos++) for (x_pos=0; x_pos<Sieve_width; x_pos++)
Pixel_in_brush(x_pos,y_pos,(Sieve[x_pos][y_pos])?Fore_color:Back_color); *(Brush_original_pixels + y_pos * Brush_width + x_pos) = (Sieve[x_pos][y_pos])?Fore_color:Back_color;
// Grab palette
memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette));
// Remap (no change)
Remap_brush();
// Copy without remap
memcpy(Brush_original_pixels, Brush, (long)Brush_height*Brush_width);
Brush_offset_X=(Brush_width>>1); Brush_offset_X=(Brush_width>>1);
Brush_offset_Y=(Brush_height>>1); Brush_offset_Y=(Brush_height>>1);

View File

@ -894,13 +894,17 @@ void Main_handler(void)
break; break;
case SPECIAL_FLIP_X : // Flip X case SPECIAL_FLIP_X : // Flip X
Hide_cursor(); 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(); Display_cursor();
action++; action++;
break; break;
case SPECIAL_FLIP_Y : // Flip Y case SPECIAL_FLIP_Y : // Flip Y
Hide_cursor(); 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(); Display_cursor();
action++; action++;
break; break;
@ -913,6 +917,8 @@ void Main_handler(void)
case SPECIAL_ROTATE_180 : // 180° brush rotation case SPECIAL_ROTATE_180 : // 180° brush rotation
Hide_cursor(); Hide_cursor();
Rotate_180_deg_lowlevel(Brush, Brush_width, Brush_height); 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_X=(Brush_width>>1);
Brush_offset_Y=(Brush_height>>1); Brush_offset_Y=(Brush_height>>1);
Display_cursor(); Display_cursor();

View File

@ -168,7 +168,11 @@ int L_SetBrushSize(lua_State* L)
Brush_was_altered=1; Brush_was_altered=1;
// Fill with Back_color // Fill with Back_color
memset(Brush_original_pixels,Back_color,(long)Brush_width*Brush_height); 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 // Center the handle
Brush_offset_X=(Brush_width>>1); Brush_offset_X=(Brush_width>>1);
Brush_offset_Y=(Brush_height>>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(2, "putbrushpixel", y, INT_MIN, INT_MAX);
LUA_ARG_NUMBER(3, "putbrushpixel", c, INT_MIN, INT_MAX); LUA_ARG_NUMBER(3, "putbrushpixel", c, INT_MIN, INT_MAX);
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; Brush_was_altered=1;
}
if (x<0 || y<0 || x>=Brush_width || y>=Brush_height) if (x<0 || y<0 || x>=Brush_width || y>=Brush_height)
; ;

View File

@ -781,6 +781,7 @@ void Load_image(T_IO_Context *context)
free(context->Buffer_image); free(context->Buffer_image);
} }
memcpy(Brush_original_palette, context->Palette, sizeof(T_Palette)); memcpy(Brush_original_palette, context->Palette, sizeof(T_Palette));
Remap_brush();
context->Buffer_image = NULL; context->Buffer_image = NULL;
} }

View File

@ -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) 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* 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; int dx;
for (dx=Brush_height;dx!=0;dx--) for (dx=Brush_height;dx!=0;dx--)