Added Layer menu. Issue 263 and issue 110: Added background transparency, for GIF and PNG formats (tested OK in Load, Save, and preview
git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1332 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
parent
7bccc7dda2
commit
4f73c24989
@ -1672,8 +1672,7 @@ word GIF_get_next_code(void)
|
|||||||
|
|
||||||
void GIF_new_pixel(T_IO_Context * context, T_GIF_IDB *idb, byte color)
|
void GIF_new_pixel(T_IO_Context * context, T_GIF_IDB *idb, byte color)
|
||||||
{
|
{
|
||||||
if (color != context->Transparent_color) // transparent color
|
Set_pixel(context, idb->Pos_X+GIF_pos_X, idb->Pos_Y+GIF_pos_Y,color);
|
||||||
Set_pixel(context, idb->Pos_X+GIF_pos_X, idb->Pos_Y+GIF_pos_Y,color);
|
|
||||||
|
|
||||||
GIF_pos_X++;
|
GIF_pos_X++;
|
||||||
|
|
||||||
@ -1855,9 +1854,17 @@ void Load_GIF(T_IO_Context * context)
|
|||||||
&& Read_byte(GIF_file,&(GCE.Transparent_color)))
|
&& Read_byte(GIF_file,&(GCE.Transparent_color)))
|
||||||
{
|
{
|
||||||
if (GCE.Packed_fields & 1)
|
if (GCE.Packed_fields & 1)
|
||||||
|
{
|
||||||
|
if (number_LID == 0)
|
||||||
|
context->Background_transparent = 1;
|
||||||
context->Transparent_color= GCE.Transparent_color;
|
context->Transparent_color= GCE.Transparent_color;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
context->Transparent_color = -1;
|
{
|
||||||
|
if (number_LID == 0)
|
||||||
|
context->Background_transparent = 0;
|
||||||
|
context->Transparent_color = 0; // Reset transparent color
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2170,7 +2177,7 @@ void Save_GIF(T_IO_Context * context)
|
|||||||
LSDB.Height=context->Height;
|
LSDB.Height=context->Height;
|
||||||
}
|
}
|
||||||
LSDB.Resol =0x97; // Image en 256 couleurs, avec une palette
|
LSDB.Resol =0x97; // Image en 256 couleurs, avec une palette
|
||||||
LSDB.Backcol=0;
|
LSDB.Backcol=context->Transparent_color;
|
||||||
LSDB.Aspect =0; // Palette normale
|
LSDB.Aspect =0; // Palette normale
|
||||||
|
|
||||||
// On sauve le LSDB dans le fichier
|
// On sauve le LSDB dans le fichier
|
||||||
@ -2213,9 +2220,15 @@ void Save_GIF(T_IO_Context * context)
|
|||||||
current_layer++)
|
current_layer++)
|
||||||
{
|
{
|
||||||
// Write a Graphic Control Extension
|
// Write a Graphic Control Extension
|
||||||
char GCE_block[] = "\x21\xF9\x04\x05\x05\x00\x00\x00";
|
char GCE_block[] = "\x21\xF9\x04\x04\x05\x00\x00\x00";
|
||||||
//if (Main_current_layer > 0)
|
// 'Default' values:
|
||||||
// GCE_block[3] = '\x05';
|
// Disposal method "Do not dispose"
|
||||||
|
// Duration 5/100s (minimum viable value for current web browsers)
|
||||||
|
|
||||||
|
if (current_layer > 0 || context->Background_transparent)
|
||||||
|
GCE_block[3] |= 1; // Transparent color flag
|
||||||
|
GCE_block[6] = context->Transparent_color;
|
||||||
|
|
||||||
Set_layer(context, current_layer);
|
Set_layer(context, current_layer);
|
||||||
|
|
||||||
if (current_layer == context->Nb_layers -1)
|
if (current_layer == context->Nb_layers -1)
|
||||||
@ -3231,6 +3244,9 @@ void Load_PNG(T_IO_Context * context)
|
|||||||
char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier
|
char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier
|
||||||
byte png_header[8];
|
byte png_header[8];
|
||||||
byte row_pointers_allocated;
|
byte row_pointers_allocated;
|
||||||
|
png_bytep trans;
|
||||||
|
int num_trans;
|
||||||
|
png_color_16p trans_values;
|
||||||
|
|
||||||
png_structp png_ptr;
|
png_structp png_ptr;
|
||||||
png_infop info_ptr;
|
png_infop info_ptr;
|
||||||
@ -3388,11 +3404,24 @@ void Load_PNG(T_IO_Context * context)
|
|||||||
free(palette);
|
free(palette);
|
||||||
palette = NULL;
|
palette = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (color_type != PNG_COLOR_TYPE_RGB && color_type != PNG_COLOR_TYPE_RGB_ALPHA)
|
if (color_type != PNG_COLOR_TYPE_RGB && color_type != PNG_COLOR_TYPE_RGB_ALPHA)
|
||||||
{
|
{
|
||||||
Palette_loaded(context);
|
Palette_loaded(context);
|
||||||
}
|
}
|
||||||
|
// Transparency (tRNS)
|
||||||
|
if (png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values))
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; i<num_trans; i++)
|
||||||
|
{
|
||||||
|
if (trans[i]==0)
|
||||||
|
{
|
||||||
|
context->Transparent_color = i;
|
||||||
|
context->Background_transparent = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
context->Width=info_ptr->width;
|
context->Width=info_ptr->width;
|
||||||
context->Height=info_ptr->height;
|
context->Height=info_ptr->height;
|
||||||
@ -3546,6 +3575,17 @@ void Save_PNG(T_IO_Context * context)
|
|||||||
}
|
}
|
||||||
png_set_text(png_ptr, info_ptr, text_ptr, nb_text_chunks);
|
png_set_text(png_ptr, info_ptr, text_ptr, nb_text_chunks);
|
||||||
}
|
}
|
||||||
|
if (context->Background_transparent)
|
||||||
|
{
|
||||||
|
// Transparency
|
||||||
|
byte opacity[256];
|
||||||
|
// Need to fill a segment with '255', up to the transparent color
|
||||||
|
// which will have a 0. This piece of data (1 to 256 bytes)
|
||||||
|
// will be stored in the file.
|
||||||
|
memset(opacity, 255,context->Transparent_color);
|
||||||
|
opacity[context->Transparent_color]=0;
|
||||||
|
png_set_tRNS(png_ptr, info_ptr, opacity, (int)1 + context->Transparent_color,0);
|
||||||
|
}
|
||||||
switch(Pixel_ratio)
|
switch(Pixel_ratio)
|
||||||
{
|
{
|
||||||
case PIXEL_WIDE:
|
case PIXEL_WIDE:
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
BIN
fonts/GrafX2_Dark.gif
Normal file
BIN
fonts/GrafX2_Dark.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
88
layers.c
88
layers.c
@ -25,6 +25,10 @@
|
|||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "pages.h"
|
#include "pages.h"
|
||||||
|
#include "sdlscreen.h"
|
||||||
|
#include "input.h"
|
||||||
|
#include "help.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
void Layer_activate(byte layer, short side)
|
void Layer_activate(byte layer, short side)
|
||||||
{
|
{
|
||||||
@ -164,9 +168,93 @@ void Button_Layer_toggle(void)
|
|||||||
Layer_activate(layer, RIGHT_SIDE);
|
Layer_activate(layer, RIGHT_SIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Draw_transparent_color(byte color)
|
||||||
|
{
|
||||||
|
char buf[4];
|
||||||
|
Num2str(color, buf, 3);
|
||||||
|
Print_in_window(63,39,buf,MC_Black,MC_Light);
|
||||||
|
Window_rectangle(90,39,13,7,color);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Draw_transparent_background(byte background)
|
||||||
|
{
|
||||||
|
Print_in_window(99,57,background?"X":" ",MC_Black,MC_Light);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Button_Layer_menu(void)
|
void Button_Layer_menu(void)
|
||||||
{
|
{
|
||||||
|
byte transparent_color = Main_backups->Pages->Transparent_color;
|
||||||
|
byte transparent_background = Main_backups->Pages->Background_transparent;
|
||||||
|
short clicked_button;
|
||||||
|
byte color;
|
||||||
|
byte click;
|
||||||
|
|
||||||
|
Open_window(122,100,"Layers");
|
||||||
|
|
||||||
|
Window_display_frame_in( 6, 21,110, 52);
|
||||||
|
Print_in_window(14,18,"Transparency",MC_Dark,MC_Light);
|
||||||
|
|
||||||
|
Print_in_window(11,38,"Color",MC_Black,MC_Light);
|
||||||
|
Window_set_normal_button(54, 36, 56,13,"" , 0,1,KEY_NONE); // 1
|
||||||
|
Draw_transparent_color(transparent_color);
|
||||||
|
|
||||||
|
Print_in_window(11,57,"Background",MC_Black,MC_Light);
|
||||||
|
Window_set_normal_button(95, 54, 15,13,"" , 0,1,KEY_NONE); // 2
|
||||||
|
Draw_transparent_background(transparent_background);
|
||||||
|
|
||||||
|
Window_set_normal_button( 7, 78, 51,14,"OK" , 0,1,SDLK_RETURN); // 3
|
||||||
|
Window_set_normal_button(63, 78, 51,14,"Cancel", 0,1,KEY_ESC); // 4
|
||||||
|
|
||||||
|
Update_window_area(0,0,Window_width, Window_height);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
|
||||||
|
clicked_button=Window_clicked_button();
|
||||||
|
//if (Is_shortcut(Key,0x100+BUTTON_HELP))
|
||||||
|
// Window_help(BUTTON_LAYERS, NULL);
|
||||||
|
switch(clicked_button)
|
||||||
|
{
|
||||||
|
case 1: // color
|
||||||
|
Get_color_behind_window(&color,&click);
|
||||||
|
if (click && transparent_color!=color)
|
||||||
|
{
|
||||||
|
transparent_color=color;
|
||||||
|
Hide_cursor();
|
||||||
|
Draw_transparent_color(transparent_color);
|
||||||
|
Display_cursor();
|
||||||
|
Wait_end_of_click();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // background
|
||||||
|
transparent_background = !transparent_background;
|
||||||
|
Hide_cursor();
|
||||||
|
Draw_transparent_background(transparent_background);
|
||||||
|
Display_cursor();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (clicked_button<3);
|
||||||
|
|
||||||
|
// On exit
|
||||||
Hide_cursor();
|
Hide_cursor();
|
||||||
|
Close_window();
|
||||||
|
if (clicked_button==3)
|
||||||
|
{
|
||||||
|
// Accept changes
|
||||||
|
if (Main_backups->Pages->Transparent_color != transparent_color ||
|
||||||
|
Main_backups->Pages->Background_transparent != transparent_background)
|
||||||
|
{
|
||||||
|
Backup_layers(-1);
|
||||||
|
Main_backups->Pages->Transparent_color = transparent_color;
|
||||||
|
Main_backups->Pages->Background_transparent = transparent_background;
|
||||||
|
Redraw_layered_image();
|
||||||
|
Display_all_screen();
|
||||||
|
End_of_modification();
|
||||||
|
}
|
||||||
|
}
|
||||||
Unselect_button(BUTTON_LAYER_MENU);
|
Unselect_button(BUTTON_LAYER_MENU);
|
||||||
Display_cursor();
|
Display_cursor();
|
||||||
}
|
}
|
||||||
|
|||||||
21
loadsave.c
21
loadsave.c
@ -179,6 +179,11 @@ void Set_pixel(T_IO_Context *context, short x_pos, short y_pos, byte color)
|
|||||||
|
|
||||||
// Chargement des pixels dans la preview
|
// Chargement des pixels dans la preview
|
||||||
case CONTEXT_PREVIEW:
|
case CONTEXT_PREVIEW:
|
||||||
|
// Skip pixels of transparent index if :
|
||||||
|
// - It's the first layer, and image has transparent background.
|
||||||
|
// - or it's a layer above the first one
|
||||||
|
if (color == context->Transparent_color && (context->Current_layer > 0 || context->Background_transparent))
|
||||||
|
break;
|
||||||
if (((x_pos % context->Preview_factor_X)==0) && ((y_pos % context->Preview_factor_Y)==0))
|
if (((x_pos % context->Preview_factor_X)==0) && ((y_pos % context->Preview_factor_Y)==0))
|
||||||
{
|
{
|
||||||
if (context->Ratio == PIXEL_WIDE &&
|
if (context->Ratio == PIXEL_WIDE &&
|
||||||
@ -375,6 +380,8 @@ void Pre_load(T_IO_Context *context, short width, short height, long file_size,
|
|||||||
context->Height = height;
|
context->Height = height;
|
||||||
context->Ratio = ratio;
|
context->Ratio = ratio;
|
||||||
context->Nb_layers = 1;
|
context->Nb_layers = 1;
|
||||||
|
context->Transparent_color=0;
|
||||||
|
context->Background_transparent=0;
|
||||||
|
|
||||||
switch(context->Type)
|
switch(context->Type)
|
||||||
{
|
{
|
||||||
@ -742,6 +749,10 @@ void Load_image(T_IO_Context *context)
|
|||||||
Main_current_layer = context->Nb_layers - 1;
|
Main_current_layer = context->Nb_layers - 1;
|
||||||
Main_layers_visible = (2<<Main_current_layer)-1;
|
Main_layers_visible = (2<<Main_current_layer)-1;
|
||||||
|
|
||||||
|
// Load the transparency data
|
||||||
|
Main_backups->Pages->Transparent_color = context->Transparent_color;
|
||||||
|
Main_backups->Pages->Background_transparent = context->Background_transparent;
|
||||||
|
|
||||||
// Correction des dimensions
|
// Correction des dimensions
|
||||||
if (Main_image_width<1)
|
if (Main_image_width<1)
|
||||||
Main_image_width=1;
|
Main_image_width=1;
|
||||||
@ -1032,7 +1043,6 @@ void Init_context_preview(T_IO_Context * context, char *file_name, char *file_di
|
|||||||
context->File_name = file_name;
|
context->File_name = file_name;
|
||||||
context->File_directory = file_directory;
|
context->File_directory = file_directory;
|
||||||
context->Format = Main_fileformat; // FIXME ?
|
context->Format = Main_fileformat; // FIXME ?
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Setup for loading/saving the current main image
|
/// Setup for loading/saving the current main image
|
||||||
@ -1050,6 +1060,7 @@ void Init_context_layered_image(T_IO_Context * context, char *file_name, char *f
|
|||||||
context->Nb_layers = Main_backups->Pages->Nb_layers;
|
context->Nb_layers = Main_backups->Pages->Nb_layers;
|
||||||
strcpy(context->Comment, Main_comment);
|
strcpy(context->Comment, Main_comment);
|
||||||
context->Transparent_color=Main_backups->Pages->Transparent_color;
|
context->Transparent_color=Main_backups->Pages->Transparent_color;
|
||||||
|
context->Background_transparent=Main_backups->Pages->Background_transparent;
|
||||||
if (Pixel_ratio == PIXEL_WIDE || Pixel_ratio == PIXEL_WIDE2)
|
if (Pixel_ratio == PIXEL_WIDE || Pixel_ratio == PIXEL_WIDE2)
|
||||||
context->Ratio=PIXEL_WIDE;
|
context->Ratio=PIXEL_WIDE;
|
||||||
else if (Pixel_ratio == PIXEL_TALL || Pixel_ratio == PIXEL_TALL2)
|
else if (Pixel_ratio == PIXEL_TALL || Pixel_ratio == PIXEL_TALL2)
|
||||||
@ -1082,7 +1093,8 @@ void Init_context_brush(T_IO_Context * context, char *file_name, char *file_dire
|
|||||||
context->Height = Brush_height;
|
context->Height = Brush_height;
|
||||||
context->Nb_layers = 1;
|
context->Nb_layers = 1;
|
||||||
// Solid save... could use BG color maybe
|
// Solid save... could use BG color maybe
|
||||||
context->Transparent_color=-1;
|
context->Transparent_color=0;
|
||||||
|
context->Background_transparent=0;
|
||||||
context->Ratio=PIXEL_SIMPLE;
|
context->Ratio=PIXEL_SIMPLE;
|
||||||
context->Target_address=Brush;
|
context->Target_address=Brush;
|
||||||
context->Pitch=Brush_width;
|
context->Pitch=Brush_width;
|
||||||
@ -1102,7 +1114,8 @@ void Init_context_surface(T_IO_Context * context, char *file_name, char *file_di
|
|||||||
// context->Width
|
// context->Width
|
||||||
// context->Height
|
// context->Height
|
||||||
context->Nb_layers = 1;
|
context->Nb_layers = 1;
|
||||||
context->Transparent_color=-1;
|
context->Transparent_color=0;
|
||||||
|
context->Background_transparent=0;
|
||||||
context->Ratio=PIXEL_SIMPLE;
|
context->Ratio=PIXEL_SIMPLE;
|
||||||
//context->Target_address
|
//context->Target_address
|
||||||
//context->Pitch
|
//context->Pitch
|
||||||
@ -1111,6 +1124,8 @@ void Init_context_surface(T_IO_Context * context, char *file_name, char *file_di
|
|||||||
/// Function to call when need to switch layers.
|
/// Function to call when need to switch layers.
|
||||||
void Set_layer(T_IO_Context *context, byte layer)
|
void Set_layer(T_IO_Context *context, byte layer)
|
||||||
{
|
{
|
||||||
|
context->Current_layer = layer;
|
||||||
|
|
||||||
if (context->Type == CONTEXT_MAIN_IMAGE)
|
if (context->Type == CONTEXT_MAIN_IMAGE)
|
||||||
{
|
{
|
||||||
// This awful thing is the part that happens on load
|
// This awful thing is the part that happens on load
|
||||||
|
|||||||
@ -56,7 +56,8 @@ typedef struct
|
|||||||
short Height;
|
short Height;
|
||||||
byte Nb_layers;
|
byte Nb_layers;
|
||||||
char Comment[COMMENT_SIZE+1];
|
char Comment[COMMENT_SIZE+1];
|
||||||
short Transparent_color;
|
byte Background_transparent;
|
||||||
|
byte Transparent_color;
|
||||||
/// Pixel ratio of the image
|
/// Pixel ratio of the image
|
||||||
enum PIXEL_RATIO Ratio;
|
enum PIXEL_RATIO Ratio;
|
||||||
|
|
||||||
@ -65,6 +66,9 @@ typedef struct
|
|||||||
/// Pitch: Difference of addresses between one pixel and the one just "below" it
|
/// Pitch: Difference of addresses between one pixel and the one just "below" it
|
||||||
long Pitch;
|
long Pitch;
|
||||||
|
|
||||||
|
/// Internal: during load, marks which layer is being loaded.
|
||||||
|
short Current_layer;
|
||||||
|
|
||||||
/// Internal: Used to mark truecolor images on loading. Only used by preview.
|
/// Internal: Used to mark truecolor images on loading. Only used by preview.
|
||||||
//byte Is_truecolor;
|
//byte Is_truecolor;
|
||||||
/// Internal: Temporary RGB buffer when loading 24bit images
|
/// Internal: Temporary RGB buffer when loading 24bit images
|
||||||
|
|||||||
1
pages.c
1
pages.c
@ -76,6 +76,7 @@ T_Page * New_page(byte nb_layers)
|
|||||||
page->File_format=DEFAULT_FILEFORMAT;
|
page->File_format=DEFAULT_FILEFORMAT;
|
||||||
page->Nb_layers=nb_layers;
|
page->Nb_layers=nb_layers;
|
||||||
page->Transparent_color=0; // Default transparent color
|
page->Transparent_color=0; // Default transparent color
|
||||||
|
page->Background_transparent=0;
|
||||||
page->Next = page->Prev = NULL;
|
page->Next = page->Prev = NULL;
|
||||||
}
|
}
|
||||||
return page;
|
return page;
|
||||||
|
|||||||
3
struct.h
3
struct.h
@ -347,7 +347,8 @@ 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 Background_transparent; ///< Boolean, true if Layer 0 should have transparent pixels
|
||||||
|
byte Transparent_color; ///< Index of transparent color. 0 to 255.
|
||||||
byte Nb_layers; ///< Number of layers
|
byte Nb_layers; ///< Number of layers
|
||||||
byte * Image[0]; ///< Pixel data for the (first layer of) image.
|
byte * Image[0]; ///< Pixel data for the (first layer of) image.
|
||||||
// No field after Image[] ! Dynamic layer allocation for Image[1], [2] etc.
|
// No field after Image[] ! Dynamic layer allocation for Image[1], [2] etc.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user