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:
Yves Rizoud 2010-02-09 20:04:56 +00:00
parent 7bccc7dda2
commit 4f73c24989
8 changed files with 163 additions and 14 deletions

View File

@ -1672,8 +1672,7 @@ word GIF_get_next_code(void)
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++;
@ -1855,9 +1854,17 @@ void Load_GIF(T_IO_Context * context)
&& Read_byte(GIF_file,&(GCE.Transparent_color)))
{
if (GCE.Packed_fields & 1)
{
if (number_LID == 0)
context->Background_transparent = 1;
context->Transparent_color= GCE.Transparent_color;
}
else
context->Transparent_color = -1;
{
if (number_LID == 0)
context->Background_transparent = 0;
context->Transparent_color = 0; // Reset transparent color
}
}
else
@ -2170,7 +2177,7 @@ void Save_GIF(T_IO_Context * context)
LSDB.Height=context->Height;
}
LSDB.Resol =0x97; // Image en 256 couleurs, avec une palette
LSDB.Backcol=0;
LSDB.Backcol=context->Transparent_color;
LSDB.Aspect =0; // Palette normale
// On sauve le LSDB dans le fichier
@ -2213,9 +2220,15 @@ void Save_GIF(T_IO_Context * context)
current_layer++)
{
// Write a Graphic Control Extension
char GCE_block[] = "\x21\xF9\x04\x05\x05\x00\x00\x00";
//if (Main_current_layer > 0)
// GCE_block[3] = '\x05';
char GCE_block[] = "\x21\xF9\x04\x04\x05\x00\x00\x00";
// 'Default' values:
// 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);
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
byte png_header[8];
byte row_pointers_allocated;
png_bytep trans;
int num_trans;
png_color_16p trans_values;
png_structp png_ptr;
png_infop info_ptr;
@ -3388,11 +3404,24 @@ void Load_PNG(T_IO_Context * context)
free(palette);
palette = NULL;
}
if (color_type != PNG_COLOR_TYPE_RGB && color_type != PNG_COLOR_TYPE_RGB_ALPHA)
{
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->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);
}
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)
{
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -25,6 +25,10 @@
#include "windows.h"
#include "engine.h"
#include "pages.h"
#include "sdlscreen.h"
#include "input.h"
#include "help.h"
#include "misc.h"
void Layer_activate(byte layer, short side)
{
@ -164,9 +168,93 @@ void Button_Layer_toggle(void)
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)
{
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();
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);
Display_cursor();
}

View File

@ -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
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 (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->Ratio = ratio;
context->Nb_layers = 1;
context->Transparent_color=0;
context->Background_transparent=0;
switch(context->Type)
{
@ -741,6 +748,10 @@ void Load_image(T_IO_Context *context)
Main_current_layer = context->Nb_layers - 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
if (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_directory = file_directory;
context->Format = Main_fileformat; // FIXME ?
}
/// 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;
strcpy(context->Comment, Main_comment);
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)
context->Ratio=PIXEL_WIDE;
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->Nb_layers = 1;
// Solid save... could use BG color maybe
context->Transparent_color=-1;
context->Transparent_color=0;
context->Background_transparent=0;
context->Ratio=PIXEL_SIMPLE;
context->Target_address=Brush;
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->Height
context->Nb_layers = 1;
context->Transparent_color=-1;
context->Transparent_color=0;
context->Background_transparent=0;
context->Ratio=PIXEL_SIMPLE;
//context->Target_address
//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.
void Set_layer(T_IO_Context *context, byte layer)
{
context->Current_layer = layer;
if (context->Type == CONTEXT_MAIN_IMAGE)
{
// This awful thing is the part that happens on load

View File

@ -56,7 +56,8 @@ typedef struct
short Height;
byte Nb_layers;
char Comment[COMMENT_SIZE+1];
short Transparent_color;
byte Background_transparent;
byte Transparent_color;
/// Pixel ratio of the image
enum PIXEL_RATIO Ratio;
@ -64,7 +65,10 @@ typedef struct
byte *Target_address;
/// Pitch: Difference of addresses between one pixel and the one just "below" it
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.
//byte Is_truecolor;
/// Internal: Temporary RGB buffer when loading 24bit images

View File

@ -76,6 +76,7 @@ T_Page * New_page(byte nb_layers)
page->File_format=DEFAULT_FILEFORMAT;
page->Nb_layers=nb_layers;
page->Transparent_color=0; // Default transparent color
page->Background_transparent=0;
page->Next = page->Prev = NULL;
}
return page;

View File

@ -347,7 +347,8 @@ typedef struct T_Page
byte File_format; ///< File format, in enum ::FILE_FORMATS
struct T_Page *Next; ///< Pointer to the next 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 * Image[0]; ///< Pixel data for the (first layer of) image.
// No field after Image[] ! Dynamic layer allocation for Image[1], [2] etc.