[layers] Implemented SwapUp and SwapDown (Alt-PgUp, Alt-PgDown) to change layers order; Implemented layer merge (Alt-End); improved GIF loader to read images with optimized layers (smaller) and the ones with a transparent color different than zero.
git-svn-id: svn://pulkomandy.tk/GrafX2/branches/layers@1077 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
parent
abb6204757
commit
89f2173d70
84
engine.c
84
engine.c
@ -1059,6 +1059,90 @@ void Main_handler(void)
|
|||||||
}
|
}
|
||||||
action++;
|
action++;
|
||||||
break;
|
break;
|
||||||
|
case SPECIAL_LAYER_MERGE:
|
||||||
|
if (Main_current_layer>0)
|
||||||
|
{
|
||||||
|
// Backup layer below the current
|
||||||
|
Backup_layers(1<<(Main_current_layer-1));
|
||||||
|
|
||||||
|
Merge_layer();
|
||||||
|
|
||||||
|
Redraw_layered_image();
|
||||||
|
Hide_cursor();
|
||||||
|
Display_all_screen();
|
||||||
|
Display_cursor();
|
||||||
|
End_of_modification();
|
||||||
|
}
|
||||||
|
action++;
|
||||||
|
break;
|
||||||
|
case SPECIAL_LAYER_SWAP_UP:
|
||||||
|
if (Main_current_layer < (Main_backups->Pages->Nb_layers-1))
|
||||||
|
{
|
||||||
|
byte * tmp;
|
||||||
|
dword layer_flags;
|
||||||
|
|
||||||
|
// Backup with unchanged layers
|
||||||
|
Backup_layers(0);
|
||||||
|
|
||||||
|
// swap
|
||||||
|
tmp = Main_backups->Pages->Image[Main_current_layer];
|
||||||
|
Main_backups->Pages->Image[Main_current_layer] = Main_backups->Pages->Image[Main_current_layer+1];
|
||||||
|
Main_backups->Pages->Image[Main_current_layer+1] = tmp;
|
||||||
|
|
||||||
|
// Swap visibility indicators
|
||||||
|
layer_flags = (Main_layers_visible >> Main_current_layer) & 3;
|
||||||
|
// Only needed if they are different.
|
||||||
|
if (layer_flags == 1 || layer_flags == 2)
|
||||||
|
{
|
||||||
|
// One is on, the other is off. Negating them will
|
||||||
|
// perform the swap.
|
||||||
|
Main_layers_visible ^= (3 << Main_current_layer);
|
||||||
|
}
|
||||||
|
Main_current_layer++;
|
||||||
|
|
||||||
|
Redraw_layered_image();
|
||||||
|
Hide_cursor();
|
||||||
|
Display_all_screen();
|
||||||
|
Display_cursor();
|
||||||
|
End_of_modification();
|
||||||
|
}
|
||||||
|
action++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SPECIAL_LAYER_SWAP_DOWN:
|
||||||
|
if (Main_current_layer > 0)
|
||||||
|
{
|
||||||
|
byte * tmp;
|
||||||
|
dword layer_flags;
|
||||||
|
|
||||||
|
// Backup with unchanged layers
|
||||||
|
Backup_layers(0);
|
||||||
|
|
||||||
|
// swap
|
||||||
|
tmp = Main_backups->Pages->Image[Main_current_layer];
|
||||||
|
Main_backups->Pages->Image[Main_current_layer] = Main_backups->Pages->Image[Main_current_layer-1];
|
||||||
|
Main_backups->Pages->Image[Main_current_layer-1] = tmp;
|
||||||
|
|
||||||
|
// Swap visibility indicators
|
||||||
|
layer_flags = (Main_layers_visible >> (Main_current_layer-1)) & 3;
|
||||||
|
// Only needed if they are different.
|
||||||
|
if (layer_flags == 1 || layer_flags == 2)
|
||||||
|
{
|
||||||
|
// Only needed if they are different.
|
||||||
|
// One is on, the other is off. Negating them will
|
||||||
|
// perform the swap.
|
||||||
|
Main_layers_visible ^= (3 << (Main_current_layer-1));
|
||||||
|
}
|
||||||
|
Main_current_layer--;
|
||||||
|
|
||||||
|
Redraw_layered_image();
|
||||||
|
Hide_cursor();
|
||||||
|
Display_all_screen();
|
||||||
|
Display_cursor();
|
||||||
|
End_of_modification();
|
||||||
|
}
|
||||||
|
action++;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // End of special keys
|
} // End of special keys
|
||||||
|
|||||||
109
loadsave.c
109
loadsave.c
@ -2883,24 +2883,38 @@ void Save_BMP(void)
|
|||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
word Width; // width de l'écran virtuel
|
word Width; // Width of the complete image area
|
||||||
word Height; // height de l'écran virtuel
|
word Height; // Height of the complete image area
|
||||||
byte Resol; // Informations sur la résolution (et autres)
|
byte Resol; // Informations about the resolution (and other)
|
||||||
byte Backcol; // color de fond
|
byte Backcol; // Proposed background color
|
||||||
byte Aspect; // Informations sur l'aspect ratio (et autres)
|
byte Aspect; // Informations about aspect ratio (and other)
|
||||||
} T_GIF_LSDB; // Logical Screen Descriptor Block
|
} T_GIF_LSDB; // Logical Screen Descriptor Block
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
word Pos_X; // Abscisse où devrait être affichée l'image
|
word Pos_X; // X offset where the image should be pasted
|
||||||
word Pos_Y; // Ordonnée où devrait être affichée l'image
|
word Pos_Y; // Y offset where the image should be pasted
|
||||||
word Image_width; // width de l'image
|
word Image_width; // Width of image
|
||||||
word Image_height; // height de l'image
|
word Image_height; // Height of image
|
||||||
byte Indicator; // Informations diverses sur l'image
|
byte Indicator; // Misc image information
|
||||||
byte Nb_bits_pixel; // Nb de bits par pixel
|
byte Nb_bits_pixel; // Nb de bits par pixel
|
||||||
} T_GIF_IDB; // Image Descriptor Block
|
} T_GIF_IDB; // Image Descriptor Block
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
// byte Block_identifier : 0x21
|
||||||
|
// byte Function : 0xF9
|
||||||
|
// byte Block_size // 4
|
||||||
|
byte Packed_fields; // 11100000 : Reserved
|
||||||
|
// 00011100 : Disposal method
|
||||||
|
// 00000010 : User input flag
|
||||||
|
// 00000001 : Transparent flag
|
||||||
|
word Delay_time; // Time for this frame to stay displayed
|
||||||
|
byte Transparent_color; // Which color index acts as transparent
|
||||||
|
//word Bloc_terminator; // 0x00
|
||||||
|
} T_GIF_GCE; // Graphic Control Extension
|
||||||
|
|
||||||
// -- Tester si un fichier est au format GIF --------------------------------
|
// -- Tester si un fichier est au format GIF --------------------------------
|
||||||
|
|
||||||
void Test_GIF(void)
|
void Test_GIF(void)
|
||||||
@ -2983,13 +2997,14 @@ void Test_GIF(void)
|
|||||||
|
|
||||||
// -- Affiche un nouveau pixel --
|
// -- Affiche un nouveau pixel --
|
||||||
|
|
||||||
void GIF_new_pixel(byte color)
|
void GIF_new_pixel(T_GIF_IDB *idb, byte color)
|
||||||
{
|
{
|
||||||
Pixel_load_function(GIF_pos_X,GIF_pos_Y,color);
|
if (color != Main_backups->Pages->Transparent_color) // transparent color
|
||||||
|
Pixel_load_function(idb->Pos_X+GIF_pos_X, idb->Pos_Y+GIF_pos_Y,color);
|
||||||
|
|
||||||
GIF_pos_X++;
|
GIF_pos_X++;
|
||||||
|
|
||||||
if (GIF_pos_X>=Main_image_width)
|
if (GIF_pos_X>=idb->Image_width)
|
||||||
{
|
{
|
||||||
GIF_pos_X=0;
|
GIF_pos_X=0;
|
||||||
|
|
||||||
@ -3008,7 +3023,7 @@ void Test_GIF(void)
|
|||||||
default: GIF_pos_Y+=2;
|
default: GIF_pos_Y+=2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GIF_pos_Y>=Main_image_height)
|
if (GIF_pos_Y>=idb->Image_height)
|
||||||
{
|
{
|
||||||
switch(++GIF_pass)
|
switch(++GIF_pass)
|
||||||
{
|
{
|
||||||
@ -3040,11 +3055,12 @@ void Load_GIF(void)
|
|||||||
|
|
||||||
T_GIF_LSDB LSDB;
|
T_GIF_LSDB LSDB;
|
||||||
T_GIF_IDB IDB;
|
T_GIF_IDB IDB;
|
||||||
|
T_GIF_GCE GCE;
|
||||||
|
|
||||||
word nb_colors; // Nombre de couleurs dans l'image
|
word nb_colors; // Nombre de couleurs dans l'image
|
||||||
word color_index; // index de traitement d'une couleur
|
word color_index; // index de traitement d'une couleur
|
||||||
byte size_to_read; // Nombre de données à lire (divers)
|
byte size_to_read; // Nombre de données à lire (divers)
|
||||||
byte block_indentifier; // Code indicateur du type de bloc en cours
|
byte block_identifier; // Code indicateur du type de bloc en cours
|
||||||
word initial_nb_bits; // Nb de bits au début du traitement LZW
|
word initial_nb_bits; // Nb de bits au début du traitement LZW
|
||||||
word special_case=0; // Mémoire pour le cas spécial
|
word special_case=0; // Mémoire pour le cas spécial
|
||||||
word old_code=0; // Code précédent
|
word old_code=0; // Code précédent
|
||||||
@ -3086,6 +3102,10 @@ void Load_GIF(void)
|
|||||||
Original_screen_X=LSDB.Width;
|
Original_screen_X=LSDB.Width;
|
||||||
Original_screen_Y=LSDB.Height;
|
Original_screen_Y=LSDB.Height;
|
||||||
|
|
||||||
|
Init_preview(LSDB.Width,LSDB.Height,file_size,FORMAT_GIF,PIXEL_SIMPLE);
|
||||||
|
Main_image_width=LSDB.Width;
|
||||||
|
Main_image_height=LSDB.Height;
|
||||||
|
|
||||||
// Palette globale dispo = (LSDB.Resol and $80)
|
// Palette globale dispo = (LSDB.Resol and $80)
|
||||||
// Profondeur de couleur =((LSDB.Resol and $70) shr 4)+1
|
// Profondeur de couleur =((LSDB.Resol and $70) shr 4)+1
|
||||||
// Nombre de bits/pixel = (LSDB.Resol and $07)+1
|
// Nombre de bits/pixel = (LSDB.Resol and $07)+1
|
||||||
@ -3124,10 +3144,10 @@ void Load_GIF(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// On lit un indicateur de block
|
// On lit un indicateur de block
|
||||||
Read_byte(GIF_file,&block_indentifier);
|
Read_byte(GIF_file,&block_identifier);
|
||||||
while (block_indentifier!=0x3B && !File_error)
|
while (block_identifier!=0x3B && !File_error)
|
||||||
{
|
{
|
||||||
switch (block_indentifier)
|
switch (block_identifier)
|
||||||
{
|
{
|
||||||
case 0x21: // Bloc d'extension
|
case 0x21: // Bloc d'extension
|
||||||
{
|
{
|
||||||
@ -3157,7 +3177,20 @@ void Load_GIF(void)
|
|||||||
break;
|
break;
|
||||||
case 0xF9: // Graphics Control Extension
|
case 0xF9: // Graphics Control Extension
|
||||||
// Prévu pour la transparence
|
// Prévu pour la transparence
|
||||||
|
if ( Read_byte(GIF_file,&(GCE.Packed_fields))
|
||||||
|
&& Read_word_le(GIF_file,&(GCE.Delay_time))
|
||||||
|
&& Read_byte(GIF_file,&(GCE.Transparent_color)))
|
||||||
|
{
|
||||||
|
if (GCE.Packed_fields & 1)
|
||||||
|
Main_backups->Pages->Transparent_color= GCE.Transparent_color;
|
||||||
|
else
|
||||||
|
Main_backups->Pages->Transparent_color = -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
File_error=2;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// On saute le bloc:
|
// On saute le bloc:
|
||||||
fseek(GIF_file,size_to_read,SEEK_CUR);
|
fseek(GIF_file,size_to_read,SEEK_CUR);
|
||||||
@ -3171,10 +3204,11 @@ void Load_GIF(void)
|
|||||||
case 0x2C: // Local Image Descriptor
|
case 0x2C: // Local Image Descriptor
|
||||||
{
|
{
|
||||||
// Si on a deja lu une image, c'est une GIF animée ou bizarroide, on sort.
|
// Si on a deja lu une image, c'est une GIF animée ou bizarroide, on sort.
|
||||||
if (number_LID!=0)
|
if (number_LID!=0 && Pixel_load_function==Pixel_load_in_current_screen)
|
||||||
{
|
{
|
||||||
Main_current_layer++;
|
// This a second layer/frame, or more.
|
||||||
Add_layer(Main_backups, Main_current_layer);
|
// Attempt to add a layer to current image
|
||||||
|
Add_layer(Main_backups, Main_current_layer+1);
|
||||||
}
|
}
|
||||||
number_LID++;
|
number_LID++;
|
||||||
|
|
||||||
@ -3187,11 +3221,6 @@ void Load_GIF(void)
|
|||||||
&& Read_byte(GIF_file,&(IDB.Nb_bits_pixel))
|
&& Read_byte(GIF_file,&(IDB.Nb_bits_pixel))
|
||||||
&& IDB.Image_width && IDB.Image_height)
|
&& IDB.Image_width && IDB.Image_height)
|
||||||
{
|
{
|
||||||
Main_image_width=IDB.Image_width;
|
|
||||||
Main_image_height=IDB.Image_height;
|
|
||||||
|
|
||||||
if (number_LID==1)
|
|
||||||
Init_preview(IDB.Image_width,IDB.Image_height,file_size,FORMAT_GIF,PIXEL_SIMPLE);
|
|
||||||
|
|
||||||
// Palette locale dispo = (IDB.Indicator and $80)
|
// Palette locale dispo = (IDB.Indicator and $80)
|
||||||
// Image entrelacée = (IDB.Indicator and $40)
|
// Image entrelacée = (IDB.Indicator and $40)
|
||||||
@ -3271,7 +3300,7 @@ void Load_GIF(void)
|
|||||||
special_case=alphabet_stack[alphabet_stack_pos++]=GIF_current_code;
|
special_case=alphabet_stack[alphabet_stack_pos++]=GIF_current_code;
|
||||||
|
|
||||||
do
|
do
|
||||||
GIF_new_pixel(alphabet_stack[--alphabet_stack_pos]);
|
GIF_new_pixel(&IDB, alphabet_stack[--alphabet_stack_pos]);
|
||||||
while (alphabet_stack_pos!=0);
|
while (alphabet_stack_pos!=0);
|
||||||
|
|
||||||
alphabet_prefix[alphabet_free ]=old_code;
|
alphabet_prefix[alphabet_free ]=old_code;
|
||||||
@ -3291,7 +3320,7 @@ void Load_GIF(void)
|
|||||||
alphabet_free =nb_colors+2;
|
alphabet_free =nb_colors+2;
|
||||||
special_case =GIF_get_next_code();
|
special_case =GIF_get_next_code();
|
||||||
old_code =GIF_current_code;
|
old_code =GIF_current_code;
|
||||||
GIF_new_pixel(GIF_current_code);
|
GIF_new_pixel(&IDB, GIF_current_code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3302,7 +3331,7 @@ void Load_GIF(void)
|
|||||||
|
|
||||||
if (File_error>=0)
|
if (File_error>=0)
|
||||||
if ( /* (GIF_pos_X!=0) || */
|
if ( /* (GIF_pos_X!=0) || */
|
||||||
( ( (!GIF_interlaced) && (GIF_pos_Y!=Main_image_height) ) ||
|
( ( (!GIF_interlaced) && (GIF_pos_Y!=IDB.Image_height) ) ||
|
||||||
( (GIF_interlaced) && (!GIF_finished_interlaced_image) )
|
( (GIF_interlaced) && (!GIF_finished_interlaced_image) )
|
||||||
) )
|
) )
|
||||||
File_error=2;
|
File_error=2;
|
||||||
@ -3314,7 +3343,7 @@ void Load_GIF(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Lecture du code de fonction suivant:
|
// Lecture du code de fonction suivant:
|
||||||
Read_byte(GIF_file,&block_indentifier);
|
Read_byte(GIF_file,&block_identifier);
|
||||||
}
|
}
|
||||||
} // Le fichier contenait un LSDB
|
} // Le fichier contenait un LSDB
|
||||||
else
|
else
|
||||||
@ -3395,16 +3424,16 @@ void Load_GIF(void)
|
|||||||
|
|
||||||
// -- Lire le pixel suivant --
|
// -- Lire le pixel suivant --
|
||||||
|
|
||||||
byte GIF_next_pixel(void)
|
byte GIF_next_pixel(T_GIF_IDB *idb)
|
||||||
{
|
{
|
||||||
byte temp;
|
byte temp;
|
||||||
|
|
||||||
temp=Read_pixel_function(GIF_pos_X,GIF_pos_Y);
|
temp=Read_pixel_function(GIF_pos_X,GIF_pos_Y);
|
||||||
|
|
||||||
if (++GIF_pos_X>=Main_image_width)
|
if (++GIF_pos_X>=idb->Image_width)
|
||||||
{
|
{
|
||||||
GIF_pos_X=0;
|
GIF_pos_X=0;
|
||||||
if (++GIF_pos_Y>=Main_image_height)
|
if (++GIF_pos_Y>=idb->Image_height)
|
||||||
GIF_stop=1;
|
GIF_stop=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3430,7 +3459,7 @@ void Save_GIF(void)
|
|||||||
T_GIF_IDB IDB;
|
T_GIF_IDB IDB;
|
||||||
|
|
||||||
|
|
||||||
byte block_indentifier; // Code indicateur du type de bloc en cours
|
byte block_identifier; // Code indicateur du type de bloc en cours
|
||||||
word current_string; // Code de la chaîne en cours de traitement
|
word current_string; // Code de la chaîne en cours de traitement
|
||||||
byte current_char; // Caractère à coder
|
byte current_char; // Caractère à coder
|
||||||
word index; // index de recherche de chaîne
|
word index; // index de recherche de chaîne
|
||||||
@ -3524,7 +3553,7 @@ void Save_GIF(void)
|
|||||||
{
|
{
|
||||||
|
|
||||||
// On va écrire un block indicateur d'IDB et l'IDB du fichier
|
// On va écrire un block indicateur d'IDB et l'IDB du fichier
|
||||||
block_indentifier=0x2C;
|
block_identifier=0x2C;
|
||||||
IDB.Pos_X=0;
|
IDB.Pos_X=0;
|
||||||
IDB.Pos_Y=0;
|
IDB.Pos_Y=0;
|
||||||
IDB.Image_width=Main_image_width;
|
IDB.Image_width=Main_image_width;
|
||||||
@ -3532,7 +3561,7 @@ void Save_GIF(void)
|
|||||||
IDB.Indicator=0x07; // Image non entrelacée, pas de palette locale.
|
IDB.Indicator=0x07; // Image non entrelacée, pas de palette locale.
|
||||||
IDB.Nb_bits_pixel=8; // Image 256 couleurs;
|
IDB.Nb_bits_pixel=8; // Image 256 couleurs;
|
||||||
|
|
||||||
if ( Write_byte(GIF_file,block_indentifier) &&
|
if ( Write_byte(GIF_file,block_identifier) &&
|
||||||
Write_word_le(GIF_file,IDB.Pos_X) &&
|
Write_word_le(GIF_file,IDB.Pos_X) &&
|
||||||
Write_word_le(GIF_file,IDB.Pos_Y) &&
|
Write_word_le(GIF_file,IDB.Pos_Y) &&
|
||||||
Write_word_le(GIF_file,IDB.Image_width) &&
|
Write_word_le(GIF_file,IDB.Image_width) &&
|
||||||
@ -3567,12 +3596,12 @@ void Save_GIF(void)
|
|||||||
|
|
||||||
////////////////////////////////////////////// COMPRESSION LZW //
|
////////////////////////////////////////////// COMPRESSION LZW //
|
||||||
|
|
||||||
start=current_string=GIF_next_pixel();
|
start=current_string=GIF_next_pixel(&IDB);
|
||||||
descend=1;
|
descend=1;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
current_char=GIF_next_pixel();
|
current_char=GIF_next_pixel(&IDB);
|
||||||
|
|
||||||
// On regarde si dans la table on aurait pas une chaîne
|
// On regarde si dans la table on aurait pas une chaîne
|
||||||
// équivalente à current_string+Caractere
|
// équivalente à current_string+Caractere
|
||||||
|
|||||||
4
misc.c
4
misc.c
@ -222,7 +222,7 @@ byte Read_pixel_from_current_screen (word x,word y)
|
|||||||
byte depth;
|
byte depth;
|
||||||
byte color;
|
byte color;
|
||||||
color = *(Main_screen+y*Main_image_width+x);
|
color = *(Main_screen+y*Main_image_width+x);
|
||||||
if (color != 0) // transparent
|
if (color != Main_backups->Pages->Transparent_color) // transparent color
|
||||||
return color;
|
return color;
|
||||||
|
|
||||||
depth = *(Visible_image_depth_buffer.Image+x+y*Main_image_width);
|
depth = *(Visible_image_depth_buffer.Image+x+y*Main_image_width);
|
||||||
@ -236,7 +236,7 @@ void Pixel_in_current_screen (word x,word y,byte color,int with_preview)
|
|||||||
*(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width)=color;
|
*(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width)=color;
|
||||||
if ( depth <= Main_current_layer)
|
if ( depth <= Main_current_layer)
|
||||||
{
|
{
|
||||||
if (color == 0) // transparent
|
if (color == Main_backups->Pages->Transparent_color) // transparent color
|
||||||
// fetch pixel color from the topmost visible layer
|
// fetch pixel color from the topmost visible layer
|
||||||
color=*(Main_backups->Pages->Image[depth] + x+y*Main_image_width);
|
color=*(Main_backups->Pages->Image[depth] + x+y*Main_image_width);
|
||||||
|
|
||||||
|
|||||||
29
pages.c
29
pages.c
@ -193,7 +193,7 @@ void Redraw_layered_image(void)
|
|||||||
for (i=0; i<Main_image_width*Main_image_height; i++)
|
for (i=0; i<Main_image_width*Main_image_height; i++)
|
||||||
{
|
{
|
||||||
byte color = *(Main_backups->Pages->Image[layer]+i);
|
byte color = *(Main_backups->Pages->Image[layer]+i);
|
||||||
if (color != 0) /* transp color */
|
if (color != Main_backups->Pages->Transparent_color) // transparent color
|
||||||
{
|
{
|
||||||
*(Visible_image[0].Image+i) = color;
|
*(Visible_image[0].Image+i) = color;
|
||||||
if (layer != Main_current_layer)
|
if (layer != Main_current_layer)
|
||||||
@ -240,7 +240,7 @@ void Update_depth_buffer(void)
|
|||||||
for (i=0; i<Main_image_width*Main_image_height; i++)
|
for (i=0; i<Main_image_width*Main_image_height; i++)
|
||||||
{
|
{
|
||||||
byte color = *(Main_backups->Pages->Image[layer]+i);
|
byte color = *(Main_backups->Pages->Image[layer]+i);
|
||||||
if (color != 0) /* transp color */
|
if (color != Main_backups->Pages->Transparent_color) // transparent color
|
||||||
{
|
{
|
||||||
*(Visible_image_depth_buffer.Image+i) = layer;
|
*(Visible_image_depth_buffer.Image+i) = layer;
|
||||||
}
|
}
|
||||||
@ -259,7 +259,7 @@ void Redraw_current_layer(void)
|
|||||||
if (depth<=Main_current_layer)
|
if (depth<=Main_current_layer)
|
||||||
{
|
{
|
||||||
byte color = *(Main_backups->Pages->Image[Main_current_layer]+i);
|
byte color = *(Main_backups->Pages->Image[Main_current_layer]+i);
|
||||||
if (color != 0) /* transp color */
|
if (color != Main_backups->Pages->Transparent_color) // transparent color
|
||||||
{
|
{
|
||||||
*(Visible_image[0].Image+i) = color;
|
*(Visible_image[0].Image+i) = color;
|
||||||
}
|
}
|
||||||
@ -833,6 +833,10 @@ void Undo(void)
|
|||||||
// palette que la page courante. Mais en temps normal, le backup
|
// palette que la page courante. Mais en temps normal, le backup
|
||||||
// n'est pas utilisé à la suite d'un Undo. Donc ça ne devrait pas
|
// n'est pas utilisé à la suite d'un Undo. Donc ça ne devrait pas
|
||||||
// poser de problèmes.
|
// poser de problèmes.
|
||||||
|
|
||||||
|
if (Main_current_layer > Main_backups->Pages->Nb_layers-1)
|
||||||
|
Main_current_layer = Main_backups->Pages->Nb_layers-1;
|
||||||
|
|
||||||
Redraw_layered_image();
|
Redraw_layered_image();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -860,6 +864,10 @@ void Redo(void)
|
|||||||
// palette que la page courante. Mais en temps normal, le backup
|
// palette que la page courante. Mais en temps normal, le backup
|
||||||
// n'est pas utilisé à la suite d'un Redo. Donc ça ne devrait pas
|
// n'est pas utilisé à la suite d'un Redo. Donc ça ne devrait pas
|
||||||
// poser de problèmes.
|
// poser de problèmes.
|
||||||
|
|
||||||
|
if (Main_current_layer > Main_backups->Pages->Nb_layers-1)
|
||||||
|
Main_current_layer = Main_backups->Pages->Nb_layers-1;
|
||||||
|
|
||||||
Redraw_layered_image();
|
Redraw_layered_image();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -983,7 +991,7 @@ byte Add_layer(T_List_of_pages *list, byte layer)
|
|||||||
}
|
}
|
||||||
new_page->Image[layer]=new_image;
|
new_page->Image[layer]=new_image;
|
||||||
// Fill with transparency, initially
|
// Fill with transparency, initially
|
||||||
memset(new_image, 0, list->Pages->Height*list->Pages->Width); // transparent color
|
memset(new_image, Main_backups->Pages->Transparent_color, list->Pages->Height*list->Pages->Width); // transparent color
|
||||||
|
|
||||||
// Done. Note that the visible buffer is already ok since we
|
// Done. Note that the visible buffer is already ok since we
|
||||||
// only inserted a transparent "slide" somewhere.
|
// only inserted a transparent "slide" somewhere.
|
||||||
@ -1084,3 +1092,16 @@ byte Delete_layer(T_List_of_pages *list, byte layer)
|
|||||||
// All ok
|
// All ok
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Merges the current layer onto the one below it.
|
||||||
|
byte Merge_layer()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; i<Main_image_width*Main_image_height; i++)
|
||||||
|
{
|
||||||
|
byte color = *(Main_backups->Pages->Image[Main_current_layer]+i);
|
||||||
|
if (color != Main_backups->Pages->Transparent_color) // transparent color
|
||||||
|
*(Main_backups->Pages->Image[Main_current_layer-1]+i) = color;
|
||||||
|
}
|
||||||
|
return Delete_layer(Main_backups,Main_current_layer);
|
||||||
|
}
|
||||||
|
|||||||
2
pages.h
2
pages.h
@ -41,6 +41,8 @@ void Upload_infos_page_main(T_Page * page);
|
|||||||
byte Add_layer(T_List_of_pages *list, byte layer);
|
byte Add_layer(T_List_of_pages *list, byte layer);
|
||||||
/// Delete a layer from the latest page of a list. Returns 0 on success.
|
/// Delete a layer from the latest page of a list. Returns 0 on success.
|
||||||
byte Delete_layer(T_List_of_pages *list, byte layer);
|
byte Delete_layer(T_List_of_pages *list, byte layer);
|
||||||
|
/// Merges the current layer onto the one below it.
|
||||||
|
byte Merge_layer();
|
||||||
|
|
||||||
// private
|
// private
|
||||||
T_Page * New_page(byte nb_layers);
|
T_Page * New_page(byte nb_layers);
|
||||||
|
|||||||
5
struct.h
5
struct.h
@ -340,8 +340,10 @@ typedef struct T_Page
|
|||||||
byte File_format; ///< File format, in enum ::FILE_FORMATS
|
byte File_format; ///< File format, in enum ::FILE_FORMATS
|
||||||
struct T_Page *Next; ///< Pointer to the next backup
|
struct T_Page *Next; ///< Pointer to the next backup
|
||||||
struct T_Page *Prev; ///< Pointer to the previous backup
|
struct T_Page *Prev; ///< Pointer to the previous backup
|
||||||
|
word Transparent_color; ///< Index of transparent color. -1 or 0 to 255.
|
||||||
byte Nb_layers; ///< Number of layers
|
byte Nb_layers; ///< Number of layers
|
||||||
byte * Image[0]; ///< Pixel data for the image.
|
byte * Image[0]; ///< Pixel data for the (first layer of) image.
|
||||||
|
// No field after Image[] ! Dynamic layer allocation for Image[1], [2] etc.
|
||||||
} T_Page;
|
} T_Page;
|
||||||
|
|
||||||
/// Collection of undo/redo steps.
|
/// Collection of undo/redo steps.
|
||||||
@ -356,7 +358,6 @@ typedef struct
|
|||||||
{
|
{
|
||||||
int Width; ///< Image width in pixels.
|
int Width; ///< Image width in pixels.
|
||||||
int Height; ///< Image height in pixels.
|
int Height; ///< Image height in pixels.
|
||||||
//int Users; ///< Number of references.
|
|
||||||
byte * Image; ///< Pixel data for the image.
|
byte * Image; ///< Pixel data for the image.
|
||||||
} T_Image;
|
} T_Image;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user