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
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<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))
{
@ -1200,6 +1211,8 @@ void Stretch_brush(short x1, short y1, short x2, short y2)
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);
Brush_offset_X=(Brush_width>>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<width; x++)
buffer[x+(y*width)]=Back_color;
@ -1773,6 +1788,8 @@ void Rotate_brush(float angle)
free(new_brush);
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
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));
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).
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

View File

@ -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;
}

View File

@ -1080,10 +1080,13 @@ void Button_Sieve_menu(void)
for (y_pos=0; y_pos<Sieve_height; y_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;
// 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();
Brush_offset_X=(Brush_width>>1);
Brush_offset_Y=(Brush_height>>1);

View File

@ -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();

View File

@ -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)
;

View File

@ -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;
}

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)
{
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--)