Added eraser and blur tools.

Added inks and better handling of tools->brushes->inks relationship.
color_t is now a ase_uint32.
Added the Background layer.
Fixed bugs loading some king of BMP files.
Removed the bgcolor from the Sprite and .ase files.
Added FileData and BmpData.
Renamed dirty_put to dirty_restore_image_data.
Renamed dirty_get to dirty_save_image_data.
Added get_pretty_memsize, sprite_get_memsize, undo_get_memsize to show memory-usage.
This commit is contained in:
David Capello 2008-03-27 14:29:33 +00:00
parent c1a6959e6b
commit 61a61bd2fa
106 changed files with 3837 additions and 2639 deletions

View File

@ -1,3 +1,59 @@
2008-03-27 David A. Capello <dacap@users.sourceforge.net>
* src/commands/cmd_background_from_layer.c: Added.
2008-03-26 David A. Capello <dacap@users.sourceforge.net>
* src/raster/brush.c (regenerate_brush): Now the line-brush is
more thick (this is a "shortcut" to avoid ugly effect when the
line-brush was used to draw, for example, a ellipse).
* src/raster/sprite.c (sprite_set_imgtype): Fixed a bug where an
incorrect address was saved in the undo information.
* src/commands/cmd_cel_properties.c, data/jids/celprop.jid:
Modified to display information only (the "opacity" of the Cel is
the only field that can be modified).
* src/jinete/jfile.c (convert_tag_to_widget): Added grid support.
2008-03-25 David A. Capello <dacap@users.sourceforge.net>
* src/raster/layer.c (layer_free_images): Added to fix a bug which
the stock has images of removed layers.
* src/script/functions.c (FlattenLayers): Rewritten to use the
`Background' layer.
* src/raster/undo.c (update_undo): the undo size is get from the
configuration.
* src/dialogs/options.c (dialogs_options): Added option to change
the undo size limit per sprite.
2008-03-24 David A. Capello <dacap@users.sourceforge.net>
* src/modules/tools.c (ase_tool_eraser): Added.
* src/modules/tools.c (ase_tool_dots): Removed.
* src/modules/tools.h (struct ToolData): Added. Restructured all
the tools handling. No more real-time dirty. Now a temporary
preview image is used and them a `dirty' is created using the
differences between the old and new layer pixels.
* src/core/color.c: Removed alpha value of colors.
* src/widgets/editor.h (Editor): Added ctrl_pressed to show the
move-cursor.
* src/raster/sprite.h (struct Sprite): Removed the bgcolor
property (it's confusing).
2008-03-23 David A. Capello <dacap@users.sourceforge.net>
* src/file/filedata.[ch]: Added FileData and BmpData.
2008-03-22 David A. Capello <dacap@users.sourceforge.net>
* src/dialogs/filmedit.c (layer_box_msg_proc, cel_box_msg_proc):

View File

@ -6,7 +6,10 @@ NEWS
---
+ Added support to load and save PNG files (through 'libpng').
+ Rewritten the color-selector dialog.
+ Added the `Background' layer.
+ Transparent cel handling for the end-user (you can move a cel and
don't worry about its bounds).
+ Rewritten the color-bar and color-selector dialog.
+ Replaced the "List" menu with the tabs selector.
+ Rewritten the File Selector:
+ Preview support.
@ -28,7 +31,9 @@ NEWS
+ New XML format for the menus and keyboard shortcuts.
- Removed a lot of "complex" functionality:
- Removed mask-repositories (you can use .msk files instead).
- Removed menu scripting customization.
- Removed menu scripting customization: the scripting support is
broken, next versions of ASE will contain a better set of routines
to create scripts.
- Removed screen saver.
- Removed sessions.
- Removed draw-text (it'll return in next versions).
@ -36,9 +41,7 @@ NEWS
moment).
- Removed mapgen.
- Removed linked-cels (were complex for the end-user).
- Also the scripting support is broken, next versions of ASE will
contain a better set of routines to create scripts.
0.5
---

View File

@ -1,20 +1,20 @@
Next beta
---------
- add the progress bar for effects and save-file.
- add layer_from_background
- fix colors
- tooltips for color-bar.
+ agregar soporte para UNDO al cambiar los colores de la paleta.
- si está activado el cuadro para configurar herramientas las teclas G
y H deben actualizarlo
+ Solución: con hooks y Options (agregar core/options.[ch])
- fix this bug:
+ Create a RGB image,
+ change color mode to Indexed,
+ Undo (with the mouse).
High priority work
------------------
- search for TODO;
- if there is activated the Tools Configuration dialog box, the
Shift+G and Shift+S should update it
+ Solution: with hooks and Options (add core/options.[ch])
- add a consistent error handling.
- rewrite the film editor.
- rewrite tools-inks-drawingmode stuff;
- new animation editor (remove the film editor)

View File

@ -24,7 +24,7 @@
#define __ASE_CONFIG_H
/* general information */
#define PACKAGE "ase"
#define PACKAGE "ASE"
#define VERSION "0.6b2"
#define WEBSITE "http://www.aseprite.org/"
#define COPYRIGHT "Copyright (C) 2001-2008 David A. Capello"

View File

@ -2,87 +2,93 @@
<gui>
<!-- keyboard shortcuts -->
<keyboard>
<!-- file -->
<key command="new_file" shortcut="Ctrl+N" />
<key command="open_file" shortcut="Ctrl+O" />
<key command="save_file" shortcut="Ctrl+S" />
<key command="save_file_as" shortcut="Shift+Ctrl+S" />
<key command="close_file" shortcut="Ctrl+W" />
<key command="close_all_files" shortcut="Shift+Ctrl+W" />
<key command="screen_shot" shortcut="F12" />
<key command="exit" shortcut="Ctrl+Q" />
<key command="exit" shortcut="Esc" />
<!-- edit -->
<key command="undo" shortcut="Ctrl+Z" /> <key command="undo" shortcut="Ctrl+U" />
<key command="redo" shortcut="Ctrl+R" />
<key command="cut" shortcut="Ctrl+X" /> <key command="cut" shortcut="Shift+Del" />
<key command="copy" shortcut="Ctrl+C" /> <key command="copy" shortcut="Ctrl+Ins" />
<key command="paste" shortcut="Ctrl+V" /> <key command="paste" shortcut="Shift+Ins" />
<key command="clear" shortcut="Ctrl+B" /> <key command="clear" shortcut="Ctrl+Del" />
<key command="flip_horizontal" shortcut="Shift+H" />
<key command="flip_vertical" shortcut="Shift+V" />
<key command="replace_color" shortcut="Shift+R" />
<key command="invert_color" shortcut="Ctrl+I" />
<!-- sprite -->
<key command="sprite_properties" shortcut="Ctrl+P" />
<!-- layer -->
<key command="layer_properties" shortcut="Shift+P" />
<key command="new_layer" shortcut="Shift+N" />
<!-- frame -->
<key command="new_frame" shortcut="N" />
<key command="goto_first_frame" shortcut="Home" />
<key command="goto_previous_frame" shortcut="Left" />
<key command="goto_next_frame" shortcut="Right" />
<key command="goto_last_frame" shortcut="End" />
<key command="play_animation" shortcut="Enter" />
<!-- cel -->
<key command="cel_properties" shortcut="Shift+Ctrl+P" />
<key command="new_cel" shortcut="Shift+Ctrl+N" />
<!-- mask -->
<key command="mask_all" shortcut="Ctrl+A" />
<key command="deselect_mask" shortcut="Ctrl+D" />
<key command="reselect_mask" shortcut="Shift+Ctrl+D" />
<key command="invert_mask" shortcut="Shift+Ctrl+I" />
<!-- view -->
<key command="refresh" shortcut="F5" />
<key command="advanced_mode" shortcut="A" />
<key command="make_unique_editor" shortcut="Ctrl+1" />
<key command="split_editor_vertically" shortcut="Ctrl+2" />
<key command="split_editor_horizontally" shortcut="Ctrl+3" />
<key command="close_editor" shortcut="Ctrl+4" />
<key command="preview_fit_to_screen" shortcut="F6" />
<key command="preview_normal" shortcut="F7" />
<key command="preview_tiled" shortcut="F8" />
<key command="show_grid" shortcut="G" />
<key command="snap_to_grid" shortcut="H" />
<!-- tools -->
<key command="configure_tools" shortcut="C" />
<key command="marker_tool" shortcut="M" />
<key command="dots_tool" shortcut="D" />
<key command="pencil_tool" shortcut="P" />
<key command="brush_tool" shortcut="B" />
<key command="spray_tool" shortcut="S" />
<key command="floodfill_tool" shortcut="F" />
<key command="line_tool" shortcut="L" />
<!-- <key command="bezier_tool" shortcut="V" /> -->
<key command="rectangle_tool" shortcut="R" />
<key command="ellipse_tool" shortcut="E" />
<key command="eyedropper_tool" shortcut="I" />
<key command="switch_colors" shortcut="X" />
<key command="film_editor" shortcut="Tab" />
<key command="convolution_matrix" shortcut="F9" />
<key command="color_curve" shortcut="Ctrl+M" />
<key command="color_curve" shortcut="F10" />
<!-- <key command="run_script" shortcut="Ctrl+0" /> -->
<key command="tips" shortcut="F1" />
<key command="options" shortcut="Shift+Ctrl+O" />
<commands>
<!-- file -->
<key command="new_file" shortcut="Ctrl+N" />
<key command="open_file" shortcut="Ctrl+O" />
<key command="save_file" shortcut="Ctrl+S" />
<key command="save_file_as" shortcut="Shift+Ctrl+S" />
<key command="close_file" shortcut="Ctrl+W" />
<key command="close_all_files" shortcut="Shift+Ctrl+W" />
<key command="screen_shot" shortcut="F12" />
<key command="exit" shortcut="Ctrl+Q" />
<key command="exit" shortcut="Esc" />
<!-- edit -->
<key command="undo" shortcut="Ctrl+Z" /> <key command="undo" shortcut="Ctrl+U" />
<key command="redo" shortcut="Ctrl+R" />
<key command="cut" shortcut="Ctrl+X" /> <key command="cut" shortcut="Shift+Del" />
<key command="copy" shortcut="Ctrl+C" /> <key command="copy" shortcut="Ctrl+Ins" />
<key command="paste" shortcut="Ctrl+V" /> <key command="paste" shortcut="Shift+Ins" />
<key command="clear" shortcut="Ctrl+B" /> <key command="clear" shortcut="Ctrl+Del" />
<key command="flip_horizontal" shortcut="Shift+H" />
<key command="flip_vertical" shortcut="Shift+V" />
<key command="replace_color" shortcut="Shift+R" />
<key command="invert_color" shortcut="Ctrl+I" />
<!-- sprite -->
<key command="sprite_properties" shortcut="Ctrl+P" />
<!-- layer -->
<key command="layer_properties" shortcut="Shift+P" />
<key command="new_layer" shortcut="Shift+N" />
<!-- frame -->
<key command="new_frame" shortcut="N" />
<key command="goto_first_frame" shortcut="Home" />
<key command="goto_previous_frame" shortcut="Left" />
<key command="goto_next_frame" shortcut="Right" />
<key command="goto_last_frame" shortcut="End" />
<key command="play_animation" shortcut="Enter" />
<!-- cel -->
<key command="cel_properties" shortcut="Shift+Ctrl+P" />
<key command="new_cel" shortcut="Shift+Ctrl+N" />
<!-- mask -->
<key command="mask_all" shortcut="Ctrl+A" />
<key command="deselect_mask" shortcut="Ctrl+D" />
<key command="reselect_mask" shortcut="Shift+Ctrl+D" />
<key command="invert_mask" shortcut="Shift+Ctrl+I" />
<!-- view -->
<key command="refresh" shortcut="F5" />
<key command="advanced_mode" shortcut="A" />
<key command="make_unique_editor" shortcut="Ctrl+1" />
<key command="split_editor_vertically" shortcut="Ctrl+2" />
<key command="split_editor_horizontally" shortcut="Ctrl+3" />
<key command="close_editor" shortcut="Ctrl+4" />
<key command="preview_fit_to_screen" shortcut="F6" />
<key command="preview_normal" shortcut="F7" />
<key command="preview_tiled" shortcut="F8" />
<key command="show_grid" shortcut="Shift+G" />
<key command="snap_to_grid" shortcut="Shift+S" />
<!-- tools -->
<key command="configure_tools" shortcut="C" />
<key command="film_editor" shortcut="Tab" />
<key command="convolution_matrix" shortcut="F9" />
<key command="color_curve" shortcut="Ctrl+M" />
<key command="color_curve" shortcut="F10" />
<!-- <key command="run_script" shortcut="Ctrl+0" /> -->
<key command="tips" shortcut="F1" />
<key command="options" shortcut="Shift+Ctrl+O" />
<!-- others -->
<key command="eyedropper" shortcut="I" />
<key command="switch_colors" shortcut="X" />
</commands>
<tools>
<key tool="rectangular_marquee" shortcut="M" />
<key tool="eraser" shortcut="E" />
<key tool="pencil" shortcut="B" />
<key tool="brush" shortcut="B" />
<key tool="spray" shortcut="S" />
<key tool="paint_bucket" shortcut="G" />
<key tool="line" shortcut="L" />
<key tool="rectangle" shortcut="U" />
<key tool="ellipse" shortcut="U" />
<key tool="blur" shortcut="R" />
</tools>
</keyboard>
<!-- main bar menu -->
<menu id="main_menu">
<menu name="&File">
<item command="new_file" name="&New" />
<item command="open_file" name="&Open" />
<item command="new_file" name="&New..." />
<item command="open_file" name="&Open..." />
<item id="recent_list" name="Open &Recent" />
<separator />
<item command="save_file" name="&Save" />
@ -109,32 +115,34 @@
<item command="flip_horizontal" name="Flip &Horizontal" />
<item command="flip_vertical" name="Flip &Vertical" />
<separator />
<item command="replace_color" name="R&eplace Color" />
<item command="replace_color" name="R&eplace Color..." />
<item command="invert_color" name="&Invert" />
</menu>
<menu name="&Sprite">
<item command="sprite_properties" name="&Properties" />
<item command="sprite_properties" name="&Properties..." />
<separator />
<item command="change_image_type" name="&Color Mode" />
<item command="change_image_type" name="&Color Mode..." />
<separator />
<item command="duplicate_sprite" name="&Duplicate" />
<item command="duplicate_sprite" name="&Duplicate..." />
<item command="crop_sprite" name="Cr&op" />
<item command="autocrop_sprite" name="&Auto Crop" />
</menu>
<menu name="&Layer" id="layer_popup">
<item command="layer_properties" name="&Properties" />
<item command="layer_properties" name="&Properties..." />
<separator />
<item command="new_layer" name="&New" />
<item command="new_layer" name="&New..." />
<!-- <item command="new_layer_set" name="New &Set" /> -->
<item command="remove_layer" name="&Remove" />
<item command="background_from_layer" name="&Background from Layer" />
<item command="layer_from_background" name="&Layer from Background..." />
<separator />
<item command="duplicate_layer" name="&Duplicate" />
<item command="duplicate_layer" name="&Duplicate..." />
<item command="merge_down_layer" name="&Merge Down" />
<item command="flatten_layers" name="&Flatten" />
<item command="crop_layer" name="Cr&op" />
</menu>
<menu name="F&rame" id="frame_popup">
<item command="frame_properties" name="&Properties" />
<item command="frame_properties" name="&Properties..." />
<separator />
<item command="new_frame" name="&New" />
<item command="remove_frame" name="&Remove" />
@ -148,7 +156,7 @@
<item command="play_animation" name="&Play" />
</menu>
<menu name="&Cel" id="cel_popup">
<item command="cel_properties" name="&Properties" />
<item command="cel_properties" name="&Properties..." />
<separator />
<item command="new_cel" name="&New" />
<item command="move_cel" name="&Move" />
@ -194,22 +202,8 @@
<item command="configure_screen" name="Configure &Screen" />
</menu>
<menu name="&Tools">
<menu name="&Drawing Tool">
<item command="configure_tools" name="&Configure" />
<separator />
<item command="marker_tool" name="&Marker" />
<item command="dots_tool" name="&Dots" />
<item command="pencil_tool" name="&Pencil" />
<item command="brush_tool" name="&Brush" />
<item command="spray_tool" name="&Spray" />
<item command="floodfill_tool" name="&Floodfill" />
<separator />
<item command="line_tool" name="&Line" />
<!-- <item command="bezier_tool" name="&Bezier" /> -->
<item command="rectangle_tool" name="&Rectangle" />
<item command="ellipse_tool" name="&Ellipse" />
<!-- <item command="oval_tool" name="&Oval" /> -->
</menu>
<item command="configure_tools" name="&Configure" />
<separator />
<item command="film_editor" name="&Film Editor" />
<item command="palette_editor" name="&Palette Editor" />
<separator />

View File

@ -3,29 +3,23 @@
<!-- Read "LEGAL.txt" for more information. -->
<jinete>
<window text="Cel Properties" name="cel_properties">
<box vertical>
<box horizontal expansive>
<box vertical homogeneous>
<label text="Frame:" />
<label text="X position:" />
<label text="Y position:" />
<label text="Opacity:" />
</box>
<box vertical homogeneous expansive>
<entry maxsize=32 name="frame" magnetic />
<entry maxsize=32 name="xpos" />
<entry maxsize=32 name="ypos" />
<slider min=0 max=255 name="opacity" minwidth="180" />
</box>
</box>
<grid columns="2">
<label text="Frame:" />
<label name="frame" />
<box horizontal>
<box horizontal expansive />
<box horizontal homogeneous>
<button text="&OK" name="ok" magnetic width="60" />
<button text="&Cancel" />
</box>
<label text="Position: " />
<label name="pos" readonly tooltip="X axis, Y axis" />
<label text="Dimension:" />
<label name="size" readonly tooltip="Width x Height (Memory size)" />
<label text="Opacity:" />
<slider min=0 max=255 name="opacity" cell_align="horizontal" width="128" />
<box horizontal homogeneous cell_hspan="2" cell_align="right">
<button text="&OK" name="ok" magnetic width="60" />
<button text="&Cancel" />
</box>
</box>
</grid>
</window>
</jinete>

View File

@ -36,6 +36,7 @@
<listitem text="Black" />
<listitem text="White" />
<listitem text="Magenta" />
<listitem text="Background Color" />
</listbox>
</view>

View File

@ -26,6 +26,12 @@
<check text="2 Click Movement" name="move_click2" />
<check text="2 Click Drawing" name="draw_click2" />
<box horizontal>
<label text="Undo size limit:" />
<entry name="undo_size_limit" maxsize="4" tooltip="Limit of memory to be used\nfor undo information per sprite.\nSpecified in megabytes." />
<label text="M" />
</box>
</box>
<box horizontal>

View File

@ -10,16 +10,12 @@
<label text="Type:" />
<label text="Size:" />
<label text="Frames:" />
<label text="Background:" />
</box>
<box vertical homogeneous expansive>
<entry text="" name="name" maxsize="256" readonly maxwidth="100" />
<label text="" name="type" />
<label text="" name="size" />
<label text="" name="frames" />
<box horizontal>
<box vertical name="bgcolor_box" />
</box>
</box>
</box>
<box horizontal>

View File

@ -34,7 +34,7 @@
</box>
<box name="brush_preview_box" /><!-- custom widget -->
</box>
<separator text="Glass Dirty:" horizontal left />
<separator text="Opacity:" horizontal left />
<slider min=0 max=255 name="glass_dirty" />
<separator text="Spray:" horizontal left />
<box horizontal>

View File

@ -67,24 +67,11 @@ WORD Color depth (bits per pixel)
8 bpp = Indexed
DWORD Flags (must be 0)
WORD Speed (milliseconds between frame, like in FLC files)
DEPRECATED!!!: you should use the frame duration
field from each frame header
DEPRECATED: You should use the frame duration
field from each frame header
DWORD Set be 0
DWORD Set be 0
BYTE[4] Background color:
For 32 bpp
BYTE Red
BYTE Green
BYTE Blue
BYTE Alpha
For 16 bpp:
BYTE Gray
BYTE Alpha
BYTE[2] Padding
For 8 bpp:
BYTE Index
BYTE[3] Padding
BYTE[96] For future (set to zero)
BYTE[100] For future (set to zero)
========================================
@ -97,7 +84,7 @@ header of 16 bytes:
DWORD Bytes in this frame
WORD Magic number (always 0xF1FA)
WORD Number of "chunks" in this frame
WORD Frame duration (in milliseconds) [NEW FIELD!!!]
WORD Frame duration (in milliseconds)
BYTE[6] For future (set to zero)
Then each chunk format is:
@ -117,30 +104,34 @@ Layer Chunk (0x2004)
In the first frame should be a set of layer chunks to determine the
entire layers layout:
WORD Flags (1=readable, 2=writable)
WORD Flags:
LAYER_IS_READABLE = 0x0001
LAYER_IS_WRITABLE = 0x0002
LAYER_IS_LOCKMOVE = 0x0004
LAYER_IS_BACKGROUND = 0x0008
WORD Layer type (0=normal (image) layer, 1=layer set)
WORD Layer child level (see NOTE.1)
WORD Default layer width in pixels (ignored)
WORD Default layer height in pixels (ignored)
WORD Blend mode (always 0 for layer set)
BLEND_MODE_NORMAL = 0
BLEND_MODE_DISSOLVE = 1
BLEND_MODE_MULTIPLY = 2
BLEND_MODE_SCREEN = 3
BLEND_MODE_OVERLAY = 4
BLEND_MODE_NORMAL = 0
BLEND_MODE_DISSOLVE = 1
BLEND_MODE_MULTIPLY = 2
BLEND_MODE_SCREEN = 3
BLEND_MODE_OVERLAY = 4
BLEND_MODE_HARD_LIGHT = 5
BLEND_MODE_DODGE = 6
BLEND_MODE_BURN = 7
BLEND_MODE_DARKEN = 8
BLEND_MODE_LIGHTEN = 9
BLEND_MODE_ADDITION = 10
BLEND_MODE_SUBTRACT = 11
BLEND_MODE_DODGE = 6
BLEND_MODE_BURN = 7
BLEND_MODE_DARKEN = 8
BLEND_MODE_LIGHTEN = 9
BLEND_MODE_ADDITION = 10
BLEND_MODE_SUBTRACT = 11
BLEND_MODE_DIFFERENCE = 12
BLEND_MODE_HUE = 13
BLEND_MODE_HUE = 13
BLEND_MODE_SATURATION = 14
BLEND_MODE_COLOR = 15
BLEND_MODE_COLOR = 15
BLEND_MODE_LUMINOSITY = 16
BLEND_MODE_COPY = 17
BLEND_MODE_COPY = 17
BYTE[4] For future (set to zero)
STRING Layer name
@ -175,7 +166,7 @@ Cel Chunk (0x2005)
XXXXX -todo-
Mask Chunk (0x2016) DEPRECATED!!!
Mask Chunk (0x2016) DEPRECATED
----------------------------------------
WORD X position
@ -244,3 +235,18 @@ File Format Changes
header. Then, if you found a frame with the frame-duration
field > 0, you should update the duration of the frame with
that value.
2) The format of ASE 0.6 beta has a header with a background color
after the two last reserved DWORD
...
WORD Speed (milliseconds between frame, like in FLC files)
DWORD Set be 0
DWORD Set be 0
DWORD Background-color <------ *
BYTE[96] For future (set to zero)
* This field is deprecated, and now it should be 0 or his value
should be completely ignored. The only drawback is that the
sprite will have a transparent background instead of a colored
one.

View File

@ -8,6 +8,7 @@ ASE = aseprite$(EXE)
COMMON_SOURCES = \
src/commands/cmd_about.c \
src/commands/cmd_advanced_mode.c \
src/commands/cmd_background_from_layer.c \
src/commands/cmd_cel_properties.c \
src/commands/cmd_change_image_type.c \
src/commands/cmd_clear.c \
@ -32,6 +33,7 @@ COMMON_SOURCES = \
src/commands/cmd_goto_frame.c \
src/commands/cmd_grid.c \
src/commands/cmd_invert_mask.c \
src/commands/cmd_layer_from_background.c \
src/commands/cmd_layer_properties.c \
src/commands/cmd_link_cel.c \
src/commands/cmd_load_mask.c \
@ -104,6 +106,7 @@ COMMON_SOURCES = \
src/file/ase_format.c \
src/file/bmp_format.c \
src/file/file.c \
src/file/filedata.c \
src/file/fli/fli.c \
src/file/fli_format.c \
src/file/gif/format.c \
@ -191,7 +194,6 @@ COMMON_SOURCES = \
src/util/celmove.c \
src/util/clipbrd.c \
src/util/col_file.c \
src/util/crop.c \
src/util/filetoks.c \
src/util/hash.c \
src/util/misc.c \

View File

@ -0,0 +1,51 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2008 David A. Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "commands/commands.h"
#include "modules/gui.h"
#include "modules/sprites.h"
#include "raster/layer.h"
#include "raster/sprite.h"
#include "script/functions.h"
static bool cmd_background_from_layer_enabled(const char *argument)
{
return
current_sprite != NULL &&
current_sprite->layer != NULL &&
sprite_get_background_layer(current_sprite) == NULL &&
layer_is_image(current_sprite->layer) &&
layer_is_readable(current_sprite->layer) &&
layer_is_writable(current_sprite->layer);
}
static void cmd_background_from_layer_execute(const char *argument)
{
BackgroundFromLayer();
update_screen_for_sprite(current_sprite);
}
Command cmd_background_from_layer = {
CMD_BACKGROUND_FROM_LAYER,
cmd_background_from_layer_enabled,
NULL,
cmd_background_from_layer_execute,
NULL
};

View File

@ -18,15 +18,20 @@
#include "config.h"
#include <allegro/unicode.h>
#include "jinete/jinete.h"
#include "commands/commands.h"
#include "core/app.h"
#include "core/core.h"
#include "modules/gui.h"
#include "modules/sprites.h"
#include "raster/cel.h"
#include "raster/image.h"
#include "raster/layer.h"
#include "raster/sprite.h"
#include "raster/stock.h"
#include "raster/undo.h"
static bool cmd_cel_properties_enabled(const char *argument)
@ -41,11 +46,13 @@ static bool cmd_cel_properties_enabled(const char *argument)
static void cmd_cel_properties_execute(const char *argument)
{
JWidget window = NULL;
JWidget entry_frame, entry_xpos, entry_ypos, slider_opacity, button_ok;
JWidget label_frame, label_pos, label_size;
JWidget slider_opacity, button_ok;
Sprite *sprite;
Layer *layer;
Cel *cel;
char buf[1024];
int memsize;
/* get current sprite */
sprite = lock_current_sprite();
@ -66,11 +73,15 @@ static void cmd_cel_properties_execute(const char *argument)
if (!window)
goto done;
entry_frame = jwidget_find_name(window, "frame");
entry_xpos = jwidget_find_name(window, "xpos");
entry_ypos = jwidget_find_name(window, "ypos");
slider_opacity = jwidget_find_name(window, "opacity");
button_ok = jwidget_find_name(window, "ok");
if (!get_widgets(window,
"frame", &label_frame,
"pos", &label_pos,
"size", &label_size,
"opacity", &slider_opacity,
"ok", &button_ok, NULL)) {
jwidget_free(window);
return;
}
/* if the layer isn't writable */
if (!layer_is_writable(layer)) {
@ -78,69 +89,52 @@ static void cmd_cel_properties_execute(const char *argument)
jwidget_disable(button_ok);
}
sprintf(buf, "%d", cel->frame+1);
jwidget_set_text(entry_frame, buf);
usprintf(buf, "%d/%d", cel->frame+1, sprite->frames);
jwidget_set_text(label_frame, buf);
sprintf(buf, "%d", cel->x);
jwidget_set_text(entry_xpos, buf);
/* position */
usprintf(buf, "%d, %d", cel->x, cel->y);
jwidget_set_text(label_pos, buf);
sprintf(buf, "%d", cel->y);
jwidget_set_text(entry_ypos, buf);
/* dimension (and memory size) */
memsize =
IMAGE_LINE_SIZE(sprite->stock->image[cel->image],
sprite->stock->image[cel->image]->w)*
sprite->stock->image[cel->image]->h;
usprintf(buf, "%dx%d (",
sprite->stock->image[cel->image]->w,
sprite->stock->image[cel->image]->h);
get_pretty_memsize(memsize,
buf+ustrsize(buf),
sizeof(buf)-ustrsize(buf));
ustrcat(buf, ")");
jwidget_set_text(label_size, buf);
/* opacity */
jslider_set_value(slider_opacity, cel->opacity);
if (layer_is_background(layer)) {
jwidget_disable(slider_opacity);
jwidget_add_tooltip_text(slider_opacity, "The `Background' layer is opaque,\n"
"you can't change its opacity.");
}
while (TRUE) {
jwindow_open_fg(window);
jwindow_open_fg(window);
if (jwindow_get_killer(window) == button_ok) {
int new_frame, new_xpos, new_ypos;
Cel *existent_cel;
if (jwindow_get_killer(window) == button_ok) {
int new_opacity = jslider_get_value(slider_opacity);
new_frame = strtol(jwidget_get_text(entry_frame), NULL, 10);
new_frame = MID(0, new_frame-1, sprite->frames-1);
existent_cel = layer_get_cel(layer, new_frame);
/* the opacity was changed? */
if (cel->opacity != new_opacity) {
if (undo_is_enabled(sprite->undo))
undo_int(sprite->undo, (GfxObj *)cel, &cel->opacity);
if (new_frame != cel->frame && existent_cel) {
jalert(_("Error"
"<<You can't move the cel to frame %d."
"<<There is already a cel in that position."
"||&OK"), new_frame+1);
}
else {
/* WE MUST REMOVE THE FRAME BEFORE CALL cel_set_frame() */
if (undo_is_enabled(sprite->undo)) {
undo_open(sprite->undo);
undo_remove_cel(sprite->undo, layer, cel);
}
/* change cel opacity */
cel_set_opacity(cel, new_opacity);
layer_remove_cel(layer, cel);
/* change cel properties */
new_xpos = strtol(jwidget_get_text(entry_xpos), NULL, 10);
new_ypos = strtol(jwidget_get_text(entry_ypos), NULL, 10);
cel_set_frame(cel, new_frame);
cel_set_position(cel,
MID(-9999, new_xpos, 9999),
MID(-9999, new_ypos, 9999));
cel_set_opacity(cel, jslider_get_value(slider_opacity));
/* add again the same cel */
if (undo_is_enabled(sprite->undo)) {
undo_add_cel(sprite->undo, layer, cel);
undo_close(sprite->undo);
}
layer_add_cel(layer, cel);
/* set the sprite position, refresh and break the loop */
sprite_set_frame(sprite, new_frame);
update_screen_for_sprite(sprite);
break;
}
update_screen_for_sprite(sprite);
}
else
break;
}
done:;

View File

@ -19,23 +19,30 @@
#include "config.h"
#include "commands/commands.h"
#include "core/app.h"
#include "modules/gui.h"
#include "modules/sprites.h"
#include "raster/layer.h"
#include "raster/sprite.h"
#include "util/misc.h"
#include "widgets/colbar.h"
static bool cmd_clear_enabled(const char *argument)
{
return current_sprite != NULL;
return
current_sprite != NULL &&
current_sprite->layer != NULL &&
layer_is_image(current_sprite->layer) &&
layer_is_readable(current_sprite->layer) &&
layer_is_writable(current_sprite->layer);
}
static void cmd_clear_execute(const char *argument)
{
/* get current sprite */
Sprite *sprite = current_sprite;
Sprite *sprite = current_sprite; /* get current sprite */
/* clear the mask */
ClearMask(color_mask());
ClearMask();
/* refresh the sprite */
update_screen_for_sprite(sprite);

View File

@ -47,7 +47,6 @@ static bool window_close_hook(JWidget widget, void *data);
static bool brush_size_slider_change_hook(JWidget widget, void *data);
static bool brush_angle_slider_change_hook(JWidget widget, void *data);
static bool brush_type_change_hook(JWidget widget, void *data);
static bool brush_mode_change_hook(JWidget widget, void *data);
static bool glass_dirty_slider_change_hook(JWidget widget, void *data);
static bool spray_width_slider_change_hook(JWidget widget, void *data);
static bool air_speed_slider_change_hook(JWidget widget, void *data);
@ -67,7 +66,6 @@ static void cmd_configure_tools_execute(const char *argument)
JWidget cursor_color, cursor_color_box;
JWidget brush_preview_box;
JWidget brush_type_box, brush_type;
JWidget brush_mode_box, brush_mode;
JWidget check_onionskin;
JWidget brush_preview;
bool first_time = FALSE;
@ -99,7 +97,6 @@ static void cmd_configure_tools_execute(const char *argument)
"cursor_color_box", &cursor_color_box,
"brush_preview_box", &brush_preview_box,
"brush_type_box", &brush_type_box,
"brush_mode_box", &brush_mode_box,
"onionskin", &check_onionskin, NULL)) {
jwidget_free(window);
window = NULL;
@ -142,19 +139,6 @@ static void cmd_configure_tools_execute(const char *argument)
brush_type = jwidget_find_name(window, "brush_type");
}
/* brush-mode */
if (first_time) {
brush_mode = group_button_new(3, 1, get_brush_mode(),
GFX_DRAWMODE_OPAQUE,
GFX_DRAWMODE_GLASS,
GFX_DRAWMODE_SEMI);
jwidget_set_name(brush_mode, "brush_mode");
}
else {
brush_mode = jwidget_find_name(window, "brush_mode");
}
if (get_filled_mode()) jwidget_select(filled);
if (get_tiled_mode()) jwidget_select(tiled);
if (get_use_grid()) jwidget_select(use_grid);
@ -171,7 +155,6 @@ static void cmd_configure_tools_execute(const char *argument)
jwidget_add_child(cursor_color_box, cursor_color);
jwidget_add_child(brush_preview_box, brush_preview);
jwidget_add_child(brush_type_box, brush_type);
jwidget_add_child(brush_mode_box, brush_mode);
/* append hooks */
HOOK(window, JI_SIGNAL_WINDOW_CLOSE, window_close_hook, 0);
@ -183,7 +166,6 @@ static void cmd_configure_tools_execute(const char *argument)
HOOK(brush_size, JI_SIGNAL_SLIDER_CHANGE, brush_size_slider_change_hook, brush_preview);
HOOK(brush_angle, JI_SIGNAL_SLIDER_CHANGE, brush_angle_slider_change_hook, brush_preview);
HOOK(brush_type, SIGNAL_GROUP_BUTTON_CHANGE, brush_type_change_hook, brush_preview);
HOOK(brush_mode, SIGNAL_GROUP_BUTTON_CHANGE, brush_mode_change_hook, 0);
HOOK(glass_dirty, JI_SIGNAL_SLIDER_CHANGE, glass_dirty_slider_change_hook, 0);
HOOK(air_speed, JI_SIGNAL_SLIDER_CHANGE, air_speed_slider_change_hook, 0);
HOOK(spray_width, JI_SIGNAL_SLIDER_CHANGE, spray_width_slider_change_hook, 0);
@ -267,20 +249,6 @@ static bool brush_type_change_hook(JWidget widget, void *data)
return TRUE;
}
static bool brush_mode_change_hook(JWidget widget, void *data)
{
int mode = group_button_get_selected(widget);
set_brush_mode(mode);
statusbar_set_text(app_get_statusbar(), 250,
"Brush mode: %s",
mode == DRAWMODE_OPAQUE ? "Opaque":
mode == DRAWMODE_GLASS ? "Glass":
mode == DRAWMODE_SEMI ? "Semi": "Unknown");
return TRUE;
}
static bool glass_dirty_slider_change_hook(JWidget widget, void *data)
{
set_glass_dirty(jslider_get_value(widget));

View File

@ -32,8 +32,8 @@ static bool cmd_copy_enabled(const char *argument)
{
if ((!current_sprite) ||
(!current_sprite->layer) ||
(!current_sprite->layer->readable) ||
(!current_sprite->layer->writable) ||
(!layer_is_readable(current_sprite->layer)) ||
(!layer_is_writable(current_sprite->layer)) ||
(!current_sprite->mask) ||
(!current_sprite->mask->bitmap))
return FALSE;

View File

@ -24,8 +24,8 @@
#include "raster/mask.h"
#include "raster/layer.h"
#include "raster/sprite.h"
#include "script/functions.h"
#include "util/autocrop.h"
#include "util/crop.h"
#include "util/misc.h"
static bool cmd_crop_enabled(const char *argument);
@ -41,7 +41,7 @@ static bool cmd_crop_sprite_enabled(const char *argument)
static void cmd_crop_sprite_execute(const char *argument)
{
crop_sprite();
CropSprite();
}
/* ======================== */
@ -69,7 +69,7 @@ static bool cmd_crop_layer_enabled(const char *argument)
static void cmd_crop_layer_execute(const char *argument)
{
crop_layer();
CropLayer();
}
/* ======================== */
@ -83,7 +83,7 @@ static bool cmd_crop_cel_enabled(const char *argument)
static void cmd_crop_cel_execute(const char *argument)
{
crop_cel();
CropCel();
}
/**********************************************************************/
@ -93,8 +93,8 @@ static bool cmd_crop_enabled(const char *argument)
{
if ((!current_sprite) ||
(!current_sprite->layer) ||
(!current_sprite->layer->readable) ||
(!current_sprite->layer->writable) ||
(!layer_is_readable(current_sprite->layer)) ||
(!layer_is_writable(current_sprite->layer)) ||
(!current_sprite->mask) ||
(!current_sprite->mask->bitmap))
return FALSE;

View File

@ -32,8 +32,8 @@ static bool cmd_cut_enabled(const char *argument)
{
if ((!current_sprite) ||
(!current_sprite->layer) ||
(!current_sprite->layer->readable) ||
(!current_sprite->layer->writable) ||
(!layer_is_readable(current_sprite->layer)) ||
(!layer_is_writable(current_sprite->layer)) ||
(!current_sprite->mask) ||
(!current_sprite->mask->bitmap))
return FALSE;

View File

@ -25,32 +25,46 @@
#include "commands/commands.h"
#include "modules/tools.h"
/* ======================== */
/* blur_tool */
/* ======================== */
static bool cmd_blur_tool_checked(const char *argument)
{
return current_tool == tools_list[TOOL_BLUR];
}
static void cmd_blur_tool_execute(const char *argument)
{
select_tool(tools_list[TOOL_BLUR]);
}
/* ======================== */
/* brush_tool */
/* ======================== */
static bool cmd_brush_tool_checked(const char *argument)
{
return current_tool && current_tool == &ase_tool_brush;
return current_tool == tools_list[TOOL_BRUSH];
}
static void cmd_brush_tool_execute(const char *argument)
{
select_tool(&ase_tool_brush);
select_tool(tools_list[TOOL_BRUSH]);
}
/* ======================== */
/* dots_tool */
/* eraser_tool */
/* ======================== */
static bool cmd_dots_tool_checked(const char *argument)
static bool cmd_eraser_tool_checked(const char *argument)
{
return current_tool && current_tool == &ase_tool_dots;
return current_tool == tools_list[TOOL_ERASER];
}
static void cmd_dots_tool_execute(const char *argument)
static void cmd_eraser_tool_execute(const char *argument)
{
select_tool(&ase_tool_dots);
select_tool(tools_list[TOOL_ERASER]);
}
/* ======================== */
@ -59,12 +73,12 @@ static void cmd_dots_tool_execute(const char *argument)
static bool cmd_ellipse_tool_checked(const char *argument)
{
return current_tool && current_tool == &ase_tool_ellipse;
return current_tool == tools_list[TOOL_ELLIPSE];
}
static void cmd_ellipse_tool_execute(const char *argument)
{
select_tool(&ase_tool_ellipse);
select_tool(tools_list[TOOL_ELLIPSE]);
}
/* ======================== */
@ -73,12 +87,12 @@ static void cmd_ellipse_tool_execute(const char *argument)
static bool cmd_floodfill_tool_checked(const char *argument)
{
return current_tool && current_tool == &ase_tool_floodfill;
return current_tool == tools_list[TOOL_FLOODFILL];
}
static void cmd_floodfill_tool_execute(const char *argument)
{
select_tool(&ase_tool_floodfill);
select_tool(tools_list[TOOL_FLOODFILL]);
}
/* ======================== */
@ -87,12 +101,12 @@ static void cmd_floodfill_tool_execute(const char *argument)
static bool cmd_line_tool_checked(const char *argument)
{
return current_tool && current_tool == &ase_tool_line;
return current_tool == tools_list[TOOL_LINE];
}
static void cmd_line_tool_execute(const char *argument)
{
select_tool(&ase_tool_line);
select_tool(tools_list[TOOL_LINE]);
}
/* ======================== */
@ -101,12 +115,12 @@ static void cmd_line_tool_execute(const char *argument)
static bool cmd_marker_tool_checked(const char *argument)
{
return current_tool && current_tool == &ase_tool_marker;
return current_tool == tools_list[TOOL_MARKER];
}
static void cmd_marker_tool_execute(const char *argument)
{
select_tool(&ase_tool_marker);
select_tool(tools_list[TOOL_MARKER]);
}
/* ======================== */
@ -115,12 +129,12 @@ static void cmd_marker_tool_execute(const char *argument)
static bool cmd_pencil_tool_checked(const char *argument)
{
return current_tool && current_tool == &ase_tool_pencil;
return current_tool == tools_list[TOOL_PENCIL];
}
static void cmd_pencil_tool_execute(const char *argument)
{
select_tool(&ase_tool_pencil);
select_tool(tools_list[TOOL_PENCIL]);
}
/* ======================== */
@ -129,12 +143,12 @@ static void cmd_pencil_tool_execute(const char *argument)
static bool cmd_rectangle_tool_checked(const char *argument)
{
return current_tool && current_tool == &ase_tool_rectangle;
return current_tool == tools_list[TOOL_RECTANGLE];
}
static void cmd_rectangle_tool_execute(const char *argument)
{
select_tool(&ase_tool_rectangle);
select_tool(tools_list[TOOL_RECTANGLE]);
}
/* ======================== */
@ -143,17 +157,25 @@ static void cmd_rectangle_tool_execute(const char *argument)
static bool cmd_spray_tool_checked(const char *argument)
{
return current_tool && current_tool == &ase_tool_spray;
return current_tool == tools_list[TOOL_SPRAY];
}
static void cmd_spray_tool_execute(const char *argument)
{
select_tool(&ase_tool_spray);
select_tool(tools_list[TOOL_SPRAY]);
}
/* ================================================ */
/* Commands */
Command cmd_blur_tool = {
CMD_BLUR_TOOL,
NULL,
cmd_blur_tool_checked,
cmd_blur_tool_execute,
NULL
};
Command cmd_brush_tool = {
CMD_BRUSH_TOOL,
NULL,
@ -162,14 +184,6 @@ Command cmd_brush_tool = {
NULL
};
Command cmd_dots_tool = {
CMD_DOTS_TOOL,
NULL,
cmd_dots_tool_checked,
cmd_dots_tool_execute,
NULL
};
Command cmd_ellipse_tool = {
CMD_ELLIPSE_TOOL,
NULL,
@ -178,6 +192,14 @@ Command cmd_ellipse_tool = {
NULL
};
Command cmd_eraser_tool = {
CMD_ERASER_TOOL,
NULL,
cmd_eraser_tool_checked,
cmd_eraser_tool_execute,
NULL
};
Command cmd_floodfill_tool = {
CMD_FLOODFILL_TOOL,
NULL,

View File

@ -53,11 +53,13 @@ static void cmd_eyedropper_tool_execute(const char *argument)
color = color_from_image(editor->sprite->imgtype,
sprite_getpixel(editor->sprite, x, y));
/* set the color of the color-bar */
if (argument != NULL && ustrcmp(argument, "background") == 0)
colorbar_set_bg_color(app_get_colorbar(), color);
else
colorbar_set_fg_color(app_get_colorbar(), color);
if (color_type(color) != COLOR_TYPE_MASK) {
/* set the color of the color-bar */
if (argument != NULL && ustrcmp(argument, "background") == 0)
colorbar_set_bg_color(app_get_colorbar(), color);
else
colorbar_set_fg_color(app_get_colorbar(), color);
}
}
Command cmd_eyedropper_tool = {

View File

@ -0,0 +1,55 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2008 David A. Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "jinete/jinete.h"
#include "commands/commands.h"
#include "modules/gui.h"
#include "modules/sprites.h"
#include "raster/cel.h"
#include "raster/layer.h"
#include "raster/sprite.h"
#include "raster/undo.h"
#include "script/functions.h"
static bool cmd_layer_from_background_enabled(const char *argument)
{
return
current_sprite != NULL &&
current_sprite->layer != NULL &&
layer_is_image(current_sprite->layer) &&
layer_is_readable(current_sprite->layer) &&
layer_is_writable(current_sprite->layer) &&
layer_is_background(current_sprite->layer);
}
static void cmd_layer_from_background_execute(const char *argument)
{
LayerFromBackground();
update_screen_for_sprite(current_sprite);
}
Command cmd_layer_from_background = {
CMD_LAYER_FROM_BACKGROUND,
cmd_layer_from_background_enabled,
NULL,
cmd_layer_from_background_execute,
NULL
};

View File

@ -141,6 +141,8 @@ static void cmd_merge_down_layer_execute(const char *argument)
sprite_set_layer(sprite, dst_layer);
layer_remove_layer(src_layer->parent_layer, src_layer);
layer_free_images(src_layer);
layer_free(src_layer);
update_screen_for_sprite(sprite);

View File

@ -37,8 +37,8 @@ static bool cmd_new_cel_enabled(const char *argument)
return
current_sprite &&
current_sprite->layer &&
current_sprite->layer->readable &&
current_sprite->layer->writable &&
layer_is_readable(current_sprite->layer) &&
layer_is_writable(current_sprite->layer) &&
layer_is_image(current_sprite->layer) &&
!layer_get_cel(current_sprite->layer, current_sprite->frame);
}

View File

@ -36,6 +36,7 @@
#include "raster/undo.h"
#include "script/functions.h"
#include "util/misc.h"
#include "widgets/colbar.h"
static int _sprite_counter = 0;
@ -51,9 +52,10 @@ static void cmd_new_file_execute(const char *argument)
color_t color;
color_t bg_table[] = {
color_mask(),
color_rgb(0, 0, 0, 255),
color_rgb(255, 255, 255, 255),
color_rgb(255, 0, 255, 255)
color_rgb(0, 0, 0),
color_rgb(255, 255, 255),
color_rgb(255, 0, 255),
colorbar_get_bg_color(app_get_colorbar())
};
/* load the window widget */
@ -110,7 +112,7 @@ static void cmd_new_file_execute(const char *argument)
/* select the color */
color = color_mask();
if (bg >= 0 && bg <= 3) {
if (bg >= 0 && bg <= 4) {
color = bg_table[bg];
ok = TRUE;
}
@ -131,8 +133,15 @@ static void cmd_new_file_execute(const char *argument)
usprintf(buf, "Sprite-%04d", ++_sprite_counter);
sprite_set_filename(sprite, buf);
/* image_clear(GetImage(), get_color_for_image(imgtype, color)); */
sprite->bgcolor = get_color_for_image(imgtype, color);
/* if the background color isn't transparent, we have to
convert the `Layer 1' in a `Background' */
if (color_type(color) != COLOR_TYPE_MASK) {
BackgroundFromLayer();
/* clear the image to */
image_clear(GetImage(sprite),
get_color_for_image(imgtype, color));
}
/* the undo should be disabled because we use NewSprite to
create it (a function for scripts) */

View File

@ -42,8 +42,8 @@ static bool cmd_new_frame_enabled(const char *argument)
return
current_sprite &&
current_sprite->layer &&
current_sprite->layer->readable &&
current_sprite->layer->writable &&
layer_is_readable(current_sprite->layer) &&
layer_is_writable(current_sprite->layer) &&
layer_is_image(current_sprite->layer);
}
@ -126,6 +126,8 @@ static bool copy_cel_in_next_frame(Sprite *sprite, Layer *layer, int frame)
/* background color */
image_clear(image, 0);
if (frame > 0)
layer_render(layer, image, 0, 0, frame-1);
/* add the image in the stock */
image_index = stock_add_image(sprite->stock, image);

View File

@ -31,8 +31,8 @@ static bool cmd_remove_cel_enabled(const char *argument)
return
current_sprite &&
current_sprite->layer &&
current_sprite->layer->readable &&
current_sprite->layer->writable &&
layer_is_readable(current_sprite->layer) &&
layer_is_writable(current_sprite->layer) &&
layer_is_image(current_sprite->layer) &&
layer_get_cel(current_sprite->layer, current_sprite->frame);
}

View File

@ -26,7 +26,9 @@
static bool cmd_remove_layer_enabled(const char *argument)
{
return current_sprite != NULL;
return
current_sprite != NULL &&
current_sprite->layer != NULL;
}
static void cmd_remove_layer_execute(const char *argument)

View File

@ -68,8 +68,10 @@ static void cmd_screen_shot_execute(const char *argument)
/* convert Allegro "BITMAP" to ASE "Image" */
if (imgtype == IMAGE_RGB) {
ase_uint32 *address = (ase_uint32 *)image->dat;
ase_uint32 *address;
for (y=0; y<image->h; ++y) {
address = (ase_uint32 *)image->line[y];
for (x=0; x<image->w; ++x) {
c = getpixel(bmp, x, y);
r = getr(c);
@ -80,8 +82,10 @@ static void cmd_screen_shot_execute(const char *argument)
}
}
else if (imgtype == IMAGE_INDEXED) {
ase_uint8 *address = (ase_uint8 *)image->dat;
ase_uint8 *address;
for (y=0; y<image->h; ++y) {
address = (ase_uint8 *)image->line[y];
for (x=0; x<image->w; ++x) {
*(address++) = getpixel(bmp, x, y);
}

View File

@ -23,6 +23,7 @@
#include "jinete/jinete.h"
#include "commands/commands.h"
#include "core/core.h"
#include "core/color.h"
#include "modules/gui.h"
#include "modules/sprites.h"
@ -42,7 +43,6 @@ static bool cmd_sprite_properties_enabled(const char *argument)
static void cmd_sprite_properties_execute(const char *argument)
{
JWidget window, killer, name, type, size, frames, speed, ok;
JWidget bgcolor_box, bgcolor_button;
Sprite *sprite = current_sprite;
char *imgtype_text;
char buf[256];
@ -57,7 +57,6 @@ static void cmd_sprite_properties_execute(const char *argument)
"type", &type,
"size", &size,
"frames", &frames,
"bgcolor_box", &bgcolor_box,
"speed", &speed,
"ok", &ok, NULL)) {
jwidget_free(window);
@ -87,20 +86,17 @@ static void cmd_sprite_properties_execute(const char *argument)
jwidget_set_text(type, imgtype_text);
/* sprite size (width and height) */
usprintf(buf, "%dx%d", sprite->w, sprite->h);
usprintf(buf, "%dx%d (", sprite->w, sprite->h);
get_pretty_memsize(sprite_get_memsize(sprite),
buf+ustrsize(buf),
sizeof(buf)-ustrsize(buf));
ustrcat(buf, ")");
jwidget_set_text(size, buf);
/* how many frames */
usprintf(buf, "%d", sprite->frames);
jwidget_set_text(frames, buf);
/* background color */
bgcolor_button = colorbutton_new(color_from_image(sprite->imgtype,
sprite->bgcolor),
current_sprite->imgtype);
jwidget_add_child(bgcolor_box, bgcolor_button);
jwindow_remap(window);
jwindow_center(window);
@ -111,25 +107,8 @@ static void cmd_sprite_properties_execute(const char *argument)
save_window_pos(window, "SpriteProperties");
killer = jwindow_get_killer(window);
if (killer == ok) {
int new_bgcolor;
/* the background color changes */
new_bgcolor = get_color_for_image(sprite->imgtype,
colorbutton_get_color(bgcolor_button));
/* set frames */
if (sprite->bgcolor != new_bgcolor) {
if (undo_is_enabled(sprite->undo))
undo_int(sprite->undo, (GfxObj *)sprite, &sprite->bgcolor);
sprite_set_bgcolor(sprite, new_bgcolor);
}
/* update sprite in editors */
update_screen_for_sprite(sprite);
if (killer == ok)
break;
}
else if (killer == speed) {
dialogs_frame_length(-1);
}

View File

@ -30,6 +30,8 @@
extern Command cmd_about;
extern Command cmd_advanced_mode;
extern Command cmd_autocrop_sprite;
extern Command cmd_background_from_layer;
extern Command cmd_blur_tool;
extern Command cmd_brush_tool;
extern Command cmd_cel_properties;
extern Command cmd_change_image_type;
@ -49,10 +51,10 @@ extern Command cmd_crop_sprite;
extern Command cmd_cut;
extern Command cmd_deselect_mask;
extern Command cmd_despeckle;
extern Command cmd_dots_tool;
extern Command cmd_duplicate_layer;
extern Command cmd_duplicate_sprite;
extern Command cmd_ellipse_tool;
extern Command cmd_eraser_tool;
extern Command cmd_exit;
extern Command cmd_eyedropper_tool;
extern Command cmd_film_editor;
@ -67,6 +69,7 @@ extern Command cmd_goto_next_frame;
extern Command cmd_goto_previous_frame;
extern Command cmd_invert_color;
extern Command cmd_invert_mask;
extern Command cmd_layer_from_background;
extern Command cmd_layer_properties;
extern Command cmd_line_tool;
extern Command cmd_link_cel;
@ -117,9 +120,12 @@ extern Command cmd_tips;
extern Command cmd_undo;
static Command *commands[] = {
&cmd_about,
&cmd_advanced_mode,
&cmd_autocrop_sprite,
&cmd_background_from_layer,
&cmd_blur_tool,
&cmd_brush_tool,
&cmd_cel_properties,
&cmd_change_image_type,
@ -139,10 +145,10 @@ static Command *commands[] = {
&cmd_cut,
&cmd_deselect_mask,
&cmd_despeckle,
&cmd_dots_tool,
&cmd_duplicate_layer,
&cmd_duplicate_sprite,
&cmd_ellipse_tool,
&cmd_eraser_tool,
&cmd_exit,
&cmd_eyedropper_tool,
&cmd_film_editor,
@ -157,6 +163,7 @@ static Command *commands[] = {
&cmd_goto_previous_frame,
&cmd_invert_color,
&cmd_invert_mask,
&cmd_layer_from_background,
&cmd_layer_properties,
&cmd_line_tool,
&cmd_link_cel,
@ -205,8 +212,7 @@ static Command *commands[] = {
&cmd_switch_colors,
&cmd_tips,
&cmd_undo,
/* { CMD_DRAW_TEXT, NULL, NULL, NULL, NULL }, */
/* { CMD_PLAY_FLIC, NULL, NULL, NULL, NULL }, */
NULL
};
@ -295,7 +301,7 @@ void command_add_key(Command *command, const char *string)
jaccel_add_keys_from_string(command->accel, buf);
}
void command_reset_keys()
void command_reset_keys(void)
{
Command **cmd;

View File

@ -24,6 +24,8 @@
#define CMD_ABOUT "about"
#define CMD_ADVANCED_MODE "advanced_mode"
#define CMD_AUTOCROP_SPRITE "autocrop_sprite"
#define CMD_BACKGROUND_FROM_LAYER "background_from_layer"
#define CMD_BLUR_TOOL "blur_tool"
#define CMD_BRUSH_TOOL "brush_tool"
#define CMD_CEL_PROPERTIES "cel_properties"
#define CMD_CHANGE_IMAGE_TYPE "change_image_type"
@ -43,10 +45,10 @@
#define CMD_CUT "cut"
#define CMD_DESELECT_MASK "deselect_mask"
#define CMD_DESPECKLE "despeckle"
#define CMD_DOTS_TOOL "dots_tool"
#define CMD_DUPLICATE_LAYER "duplicate_layer"
#define CMD_DUPLICATE_SPRITE "duplicate_sprite"
#define CMD_ELLIPSE_TOOL "ellipse_tool"
#define CMD_ERASER_TOOL "eraser_tool"
#define CMD_EXIT "exit"
#define CMD_EYEDROPPER_TOOL "eyedropper_tool"
#define CMD_FILM_EDITOR "film_editor"
@ -61,6 +63,7 @@
#define CMD_GOTO_PREVIOUS_FRAME "goto_previous_frame"
#define CMD_INVERT_COLOR "invert_color"
#define CMD_INVERT_MASK "invert_mask"
#define CMD_LAYER_FROM_BACKGROUND "layer_from_background"
#define CMD_LAYER_PROPERTIES "layer_properties"
#define CMD_LINE_TOOL "line_tool"
#define CMD_LINK_CEL "link_cel"
@ -109,8 +112,6 @@
#define CMD_SWITCH_COLORS "switch_colors"
#define CMD_TIPS "tips"
#define CMD_UNDO "undo"
/* #define CMD_DRAW_TEXT "draw_text" */
/* #define CMD_PLAY_FLIC "play_flic" */
typedef struct Command Command;
@ -132,6 +133,6 @@ void command_execute(Command *command, const char *argument);
bool command_is_key_pressed(Command *command, JMessage msg);
void command_add_key(Command *command, const char *string);
void command_reset_keys();
void command_reset_keys(void);
#endif /* COMMANDS_COMMANDS_H */

View File

@ -49,25 +49,27 @@ void console_open(void)
console_counter > 1)
return;
else {
JWidget window, box1, view, textbox, button;
JWidget window, grid, view, textbox, button;
window = jwindow_new(_("Processing..."));
if (!window)
return;
box1 = jbox_new(JI_VERTICAL);
grid = jgrid_new(1, FALSE);
view = jview_new();
textbox = jtextbox_new(NULL, JI_WORDWRAP);
button = jbutton_new(_("&Cancel"));
if (!box1 || !textbox || !button)
if (!grid || !textbox || !button)
return;
jview_attach(view, textbox);
jwidget_add_child(box1, view);
jwidget_add_child(box1, button);
jwidget_add_child(window, box1);
jwidget_set_min_size(button, 60, 0);
jgrid_add_child(grid, view, 1, 1, JI_HORIZONTAL | JI_VERTICAL);
jgrid_add_child(grid, button, 1, 1, JI_CENTER);
jwidget_add_child(window, grid);
jwidget_hide(view);
jwidget_magnetic(button, TRUE);
@ -124,12 +126,13 @@ void console_printf(const char *format, ...)
/* update the textbox */
if (!console_locked) {
JRect rect = jrect_new(0, 0, JI_SCREEN_W*9/10, JI_SCREEN_H*6/10);
console_locked = TRUE;
jwidget_set_min_size(wid_view, JI_SCREEN_W*9/10, JI_SCREEN_H*6/10);
jwidget_show(wid_view);
jwindow_remap(wid_console);
jwidget_set_rect(wid_console, rect);
jwindow_center(wid_console);
jwidget_dirty(wid_console);
}

View File

@ -49,6 +49,7 @@
#include "modules/rootmenu.h"
#include "modules/sprites.h"
#include "raster/image.h"
#include "raster/layer.h"
#include "raster/palette.h"
#include "raster/sprite.h"
#include "script/script.h"
@ -226,7 +227,7 @@ void app_loop(void)
menubar = jmenubar_new();
statusbar = statusbar_new();
colorbar = colorbar_new(box_colorbar->align);
toolbar = toolbar_new(box_toolbar->align);
toolbar = toolbar_new();
tabsbar = tabs_new(tabsbar_select_callback);
view = editor_view_new();
editor = create_new_editor();
@ -536,6 +537,34 @@ void app_default_statusbar_message(void)
"ASE " VERSION ", " COPYRIGHT);
}
int app_get_fg_color(Sprite *sprite)
{
assert(sprite != NULL);
return get_color_for_image(sprite->imgtype,
colorbar_get_fg_color(colorbar));
}
int app_get_bg_color(Sprite *sprite)
{
assert(sprite != NULL);
return get_color_for_image(sprite->imgtype,
colorbar_get_bg_color(colorbar));
}
int app_get_color_to_clear_layer(Layer *layer)
{
/* all transparent layers are cleared with the mask color */
color_t color = color_mask();
/* the `Background' is erased with the `Background Color' */
if (layer != NULL && layer_is_background(layer))
color = colorbar_get_bg_color(colorbar);
return get_color_for_image(layer->sprite->imgtype, color);
}
static void tabsbar_select_callback(JWidget tabs, void *data)
{
/* data can be NULL (the "Nothing" tab) */

View File

@ -28,6 +28,9 @@ enum {
APP_EVENTS
};
struct Layer;
struct Sprite;
bool app_init(int argc, char *argv[]);
void app_loop(void);
void app_exit(void);
@ -51,5 +54,9 @@ JWidget app_get_tabsbar(void);
void app_default_statusbar_message(void);
int app_get_fg_color(struct Sprite *sprite);
int app_get_bg_color(struct Sprite *sprite);
int app_get_color_to_clear_layer(struct Layer *layer);
#endif /* CORE_APP_H */

View File

@ -33,19 +33,21 @@
#include "raster/palette.h"
#include "widgets/colbar.h"
#define _hsva_geth _rgba_getr
#define _hsva_gets _rgba_getg
#define _hsva_getv _rgba_getb
#define _hsva_geta _rgba_geta
#define _hsva _rgba
/* #define GET_COLOR_TYPE(color) ((ase_uint32)((color).coltype)) */
/* #define GET_COLOR_DATA(color) ((ase_uint32)((color).imgcolor)) */
#define GET_COLOR_TYPE(color) ((ase_uint32)((color).coltype))
#define GET_COLOR_DATA(color) ((ase_uint32)((color).imgcolor))
#define MAKE_COLOR(type,data) (((type) << 24) | (data))
#define GET_COLOR_TYPE(color) ((color) >> 24)
#define GET_COLOR_DATA(color) ((color) & 0xffffff)
#define GET_COLOR_DATA_RGB(color) (GET_COLOR_DATA(color) & 0xffffff)
#define GET_COLOR_DATA_HSV(color) (GET_COLOR_DATA(color) & 0xffffff)
#define GET_COLOR_DATA_GRAY(color) (GET_COLOR_DATA(color) & 0xff)
#define GET_COLOR_DATA_INDEX(color) (GET_COLOR_DATA(color) & 0xff)
#define GET_COLOR_RGB(color) (GET_COLOR_DATA(color) & 0xffffffff)
#define GET_COLOR_HSV(color) (GET_COLOR_DATA(color) & 0xffffffff)
#define GET_COLOR_GRAY(color) (GET_COLOR_DATA(color) & 0xffff)
#define GET_COLOR_INDEX(color) (GET_COLOR_DATA(color) & 0xff)
#define MAKE_DATA(c1,c2,c3) (((c3) << 16) | ((c2) << 8) | (c1))
#define GET_DATA_C1(c) (((c) >> 0) & 0xff)
#define GET_DATA_C2(c) (((c) >> 8) & 0xff)
#define GET_DATA_C3(c) (((c) >> 16) & 0xff)
static int get_mask_for_bitmap(int depth);
@ -60,34 +62,29 @@ char *color_to_string(color_t color, char *buf, int size)
break;
case COLOR_TYPE_RGB:
data = GET_COLOR_RGB(color);
uszprintf(buf, size, "rgb{%d,%d,%d,%d}",
_rgba_getr(data),
_rgba_getg(data),
_rgba_getb(data),
_rgba_geta(data));
data = GET_COLOR_DATA_RGB(color);
uszprintf(buf, size, "rgb{%d,%d,%d}",
GET_DATA_C1(data),
GET_DATA_C2(data),
GET_DATA_C3(data));
break;
case COLOR_TYPE_HSV:
data = GET_COLOR_HSV(color);
uszprintf(buf, size, "hsv{%d,%d,%d,%d}",
_hsva_geth(data),
_hsva_gets(data),
_hsva_getv(data),
_hsva_geta(data));
data = GET_COLOR_DATA_HSV(color);
uszprintf(buf, size, "hsv{%d,%d,%d}",
GET_DATA_C1(data),
GET_DATA_C2(data),
GET_DATA_C3(data));
break;
case COLOR_TYPE_GRAY:
data = GET_COLOR_GRAY(color);
uszprintf(buf, size, "gray{%d,%d}",
_graya_getv(data),
_graya_geta(data));
data = GET_COLOR_DATA_GRAY(color);
uszprintf(buf, size, "gray{%d}", data);
break;
case COLOR_TYPE_INDEX:
data = GET_COLOR_INDEX(color);
uszprintf(buf, size, "index{%d}",
data);
data = GET_COLOR_DATA_INDEX(color);
uszprintf(buf, size, "index{%d}", data);
break;
}
@ -102,37 +99,29 @@ color_t string_to_color(const char *_str)
if (ustrcmp(str, "mask") != 0) {
if (ustrncmp(str, "rgb{", 4) == 0) {
int c=0, table[4] = { 0, 0, 0, 255 };
int c=0, table[3] = { 0, 0, 0 };
for (tok=ustrtok(str+4, ","); tok;
tok=ustrtok(NULL, ",")) {
if (c < 4)
if (c < 3)
table[c++] = ustrtol(tok, NULL, 10);
}
color = color_rgb(table[0], table[1], table[2], table[3]);
color = color_rgb(table[0], table[1], table[2]);
}
else if (ustrncmp(str, "hsv{", 4) == 0) {
int c=0, table[4] = { 0, 0, 0, 255 };
int c=0, table[3] = { 0, 0, 0 };
for (tok=ustrtok(str+4, ","); tok;
tok=ustrtok(NULL, ",")) {
if (c < 4)
if (c < 3)
table[c++] = ustrtol(tok, NULL, 10);
}
color = color_hsv(table[0], table[1], table[2], table[3]);
color = color_hsv(table[0], table[1], table[2]);
}
else if (ustrncmp(str, "gray{", 5) == 0) {
int c=0, table[2] = { 0, 255 };
for (tok=ustrtok(str+5, ","); tok;
tok=ustrtok(NULL, ",")) {
if (c < 2)
table[c++] = ustrtol(tok, NULL, 10);
}
color = color_gray(table[0], table[1]);
color = color_gray(ustrtol(str+5, NULL, 10));
}
else if (ustrncmp(str, "index{", 6) == 0) {
color = color_index(ustrtol(str+6, NULL, 10));
@ -157,43 +146,33 @@ bool color_equals(color_t c1, color_t c2)
color_t color_mask(void)
{
color_t c = { COLOR_TYPE_MASK, 0 };
return c;
return MAKE_COLOR(COLOR_TYPE_MASK, 0);
}
color_t color_rgb(int r, int g, int b, int a)
color_t color_rgb(int r, int g, int b)
{
color_t c = { COLOR_TYPE_RGB,
_rgba(r & 0xff,
g & 0xff,
b & 0xff,
a & 0xff) };
return c;
return MAKE_COLOR(COLOR_TYPE_RGB,
MAKE_DATA(r & 0xff,
g & 0xff,
b & 0xff));
}
color_t color_hsv(int h, int s, int v, int a)
color_t color_hsv(int h, int s, int v)
{
color_t c = { COLOR_TYPE_HSV,
_hsva(h & 0xff,
s & 0xff,
v & 0xff,
a & 0xff) };
return c;
return MAKE_COLOR(COLOR_TYPE_HSV,
MAKE_DATA(h & 0xff,
s & 0xff,
v & 0xff));
}
color_t color_gray(int g, int a)
color_t color_gray(int g)
{
color_t c = { COLOR_TYPE_GRAY,
_graya(g & 0xff,
a & 0xff) };
return c;
return MAKE_COLOR(COLOR_TYPE_GRAY, g & 0xff);
}
color_t color_index(int index)
{
color_t c = { COLOR_TYPE_INDEX,
index & 0xff };
return c;
return MAKE_COLOR(COLOR_TYPE_INDEX, index & 0xff);
}
int color_get_red(int imgtype, color_t color)
@ -207,23 +186,23 @@ int color_get_red(int imgtype, color_t color)
return 0;
case COLOR_TYPE_RGB:
return _rgba_getr(GET_COLOR_RGB(color));
return GET_DATA_C1(GET_COLOR_DATA_RGB(color));
case COLOR_TYPE_HSV: {
int c = GET_COLOR_HSV(color);
int h = _hsva_geth(c);
int s = _hsva_gets(c);
int v = _hsva_getv(c);
int c = GET_COLOR_DATA_HSV(color);
int h = GET_DATA_C1(c);
int s = GET_DATA_C2(c);
int v = GET_DATA_C3(c);
hsv_to_rgb_int(&h, &s, &v);
return h;
}
case COLOR_TYPE_GRAY:
return _graya_getv(GET_COLOR_GRAY(color));
return GET_COLOR_DATA_GRAY(color);
case COLOR_TYPE_INDEX:
return _rgba_getr(palette_get_entry(get_current_palette(),
GET_COLOR_INDEX(color)));
GET_COLOR_DATA_INDEX(color)));
}
@ -242,23 +221,23 @@ int color_get_green(int imgtype, color_t color)
return 0;
case COLOR_TYPE_RGB:
return _rgba_getg(GET_COLOR_RGB(color));
return GET_DATA_C2(GET_COLOR_DATA_RGB(color));
case COLOR_TYPE_HSV: {
int c = GET_COLOR_HSV(color);
int h = _hsva_geth(c);
int s = _hsva_gets(c);
int v = _hsva_getv(c);
int c = GET_COLOR_DATA_HSV(color);
int h = GET_DATA_C1(c);
int s = GET_DATA_C2(c);
int v = GET_DATA_C3(c);
hsv_to_rgb_int(&h, &s, &v);
return s;
}
case COLOR_TYPE_GRAY:
return _graya_getv(GET_COLOR_GRAY(color));
return GET_COLOR_DATA_GRAY(color);
case COLOR_TYPE_INDEX:
return _rgba_getg(palette_get_entry(get_current_palette(),
GET_COLOR_INDEX(color)));
GET_COLOR_DATA_INDEX(color)));
}
@ -277,23 +256,23 @@ int color_get_blue(int imgtype, color_t color)
return 0;
case COLOR_TYPE_RGB:
return _rgba_getb(GET_COLOR_RGB(color));
return GET_DATA_C3(GET_COLOR_DATA_RGB(color));
case COLOR_TYPE_HSV: {
int c = GET_COLOR_HSV(color);
int h = _hsva_geth(c);
int s = _hsva_gets(c);
int v = _hsva_getv(c);
int c = GET_COLOR_DATA_HSV(color);
int h = GET_DATA_C1(c);
int s = GET_DATA_C2(c);
int v = GET_DATA_C3(c);
hsv_to_rgb_int(&h, &s, &v);
return v;
}
case COLOR_TYPE_GRAY:
return _graya_getv(GET_COLOR_GRAY(color));
return GET_COLOR_DATA_GRAY(color);
case COLOR_TYPE_INDEX:
return _rgba_getb(palette_get_entry(get_current_palette(),
GET_COLOR_INDEX(color)));
GET_COLOR_DATA_INDEX(color)));
}
@ -309,23 +288,23 @@ int color_get_hue(int imgtype, color_t color)
return 0;
case COLOR_TYPE_RGB: {
int c = GET_COLOR_RGB(color);
int r = _rgba_getr(c);
int g = _rgba_getg(c);
int b = _rgba_getb(c);
int c = GET_COLOR_DATA_RGB(color);
int r = GET_DATA_C1(c);
int g = GET_DATA_C2(c);
int b = GET_DATA_C3(c);
rgb_to_hsv_int(&r, &g, &b);
return r;
}
case COLOR_TYPE_HSV:
return _hsva_geth(GET_COLOR_HSV(color));
return GET_DATA_C1(GET_COLOR_DATA_HSV(color));
case COLOR_TYPE_GRAY:
return 0;
case COLOR_TYPE_INDEX: {
ase_uint32 c = palette_get_entry(get_current_palette(),
GET_COLOR_INDEX(color));
GET_COLOR_DATA_INDEX(color));
int r = _rgba_getr(c);
int g = _rgba_getg(c);
int b = _rgba_getb(c);
@ -347,23 +326,23 @@ int color_get_saturation(int imgtype, color_t color)
return 0;
case COLOR_TYPE_RGB: {
int c = GET_COLOR_RGB(color);
int r = _rgba_getr(c);
int g = _rgba_getg(c);
int b = _rgba_getb(c);
int c = GET_COLOR_DATA_RGB(color);
int r = GET_DATA_C1(c);
int g = GET_DATA_C2(c);
int b = GET_DATA_C3(c);
rgb_to_hsv_int(&r, &g, &b);
return g;
}
case COLOR_TYPE_HSV:
return _hsva_gets(GET_COLOR_HSV(color));
return GET_DATA_C2(GET_COLOR_DATA_HSV(color));
case COLOR_TYPE_GRAY:
return 0;
case COLOR_TYPE_INDEX: {
ase_uint32 c = palette_get_entry(get_current_palette(),
GET_COLOR_INDEX(color));
GET_COLOR_DATA_INDEX(color));
int r = _rgba_getr(c);
int g = _rgba_getg(c);
int b = _rgba_getb(c);
@ -385,23 +364,23 @@ int color_get_value(int imgtype, color_t color)
return 0;
case COLOR_TYPE_RGB: {
int c = GET_COLOR_RGB(color);
int r = _rgba_getr(c);
int g = _rgba_getg(c);
int b = _rgba_getb(c);
int c = GET_COLOR_DATA_RGB(color);
int r = GET_DATA_C1(c);
int g = GET_DATA_C2(c);
int b = GET_DATA_C3(c);
rgb_to_hsv_int(&r, &g, &b);
return b;
}
case COLOR_TYPE_HSV:
return _hsva_getv(GET_COLOR_HSV(color));
return GET_DATA_C3(GET_COLOR_DATA_HSV(color));
case COLOR_TYPE_GRAY:
return _graya_getv(GET_COLOR_GRAY(color));
return GET_COLOR_DATA_GRAY(color);
case COLOR_TYPE_INDEX: {
ase_uint32 c = palette_get_entry(get_current_palette(),
GET_COLOR_INDEX(color));
GET_COLOR_DATA_INDEX(color));
int r = _rgba_getr(c);
int g = _rgba_getg(c);
int b = _rgba_getb(c);
@ -433,10 +412,10 @@ int color_get_index(int imgtype, color_t color)
break;
case COLOR_TYPE_GRAY:
return _graya_getv(GET_COLOR_GRAY(color));
return GET_COLOR_DATA_GRAY(color);
case COLOR_TYPE_INDEX:
return GET_COLOR_INDEX(color);
return GET_COLOR_DATA_INDEX(color);
}
@ -444,68 +423,6 @@ int color_get_index(int imgtype, color_t color)
return -1;
}
int color_get_alpha(int imgtype, color_t color)
{
switch (GET_COLOR_TYPE(color)) {
case COLOR_TYPE_MASK:
return imgtype == IMAGE_INDEXED ? 255: 0;
case COLOR_TYPE_RGB:
return _rgba_geta(GET_COLOR_RGB(color));
case COLOR_TYPE_HSV:
return _hsva_geta(GET_COLOR_HSV(color));
case COLOR_TYPE_GRAY:
return _graya_geta(GET_COLOR_RGB(color));
case COLOR_TYPE_INDEX:
return 255;
}
assert(FALSE);
return -1;
}
/* set the alpha channel in the color */
void color_set_alpha(color_t *color, int alpha)
{
int data;
switch (GET_COLOR_TYPE(*color)) {
case COLOR_TYPE_MASK:
assert(FALSE);
break;
case COLOR_TYPE_RGB:
data = GET_COLOR_RGB(*color);
*color = color_rgb(_rgba_getr(data),
_rgba_getg(data),
_rgba_getb(data), alpha);
break;
case COLOR_TYPE_HSV:
data = GET_COLOR_HSV(*color);
*color = color_hsv(_hsva_geth(data),
_hsva_gets(data),
_hsva_getv(data), alpha);
break;
case COLOR_TYPE_GRAY:
data = GET_COLOR_GRAY(*color);
*color = color_gray(_rgba_getg(data), alpha);
break;
case COLOR_TYPE_INDEX:
assert(FALSE);
break;
}
}
color_t color_from_image(int imgtype, int c)
{
color_t color = color_mask();
@ -516,21 +433,18 @@ color_t color_from_image(int imgtype, int c)
if (_rgba_geta(c) > 0) {
color = color_rgb(_rgba_getr(c),
_rgba_getg(c),
_rgba_getb(c),
_rgba_geta(c));
_rgba_getb(c));
}
break;
case IMAGE_GRAYSCALE:
if (_graya_geta(c) > 0) {
color = color_gray(_graya_getv(c),
_graya_geta(c));
color = color_gray(_graya_getv(c));
}
break;
case IMAGE_INDEXED:
if (c > 0)
color = color_index(c);
color = color_index(c);
break;
}
@ -540,13 +454,15 @@ color_t color_from_image(int imgtype, int c)
int blackandwhite(int r, int g, int b)
{
return (r*30+g*59+b*11)/100 < 128 ?
makecol(0, 0, 0): makecol(255, 255, 255);
makecol(0, 0, 0):
makecol(255, 255, 255);
}
int blackandwhite_neg(int r, int g, int b)
{
return (r*30+g*59+b*11)/100 < 128 ?
makecol(255, 255, 255): makecol(0, 0, 0);
makecol(255, 255, 255):
makecol(0, 0, 0);
}
int get_color_for_allegro(int depth, color_t color)
@ -561,36 +477,34 @@ int get_color_for_allegro(int depth, color_t color)
break;
case COLOR_TYPE_RGB:
data = GET_COLOR_RGB(color);
data = GET_COLOR_DATA_RGB(color);
c = makeacol_depth(depth,
_rgba_getr(data),
_rgba_getg(data),
_rgba_getb(data),
_rgba_geta(data));
_rgba_getb(data), 255);
break;
case COLOR_TYPE_HSV: {
int h, s, v;
data = GET_COLOR_HSV(color);
h = _hsva_geth(data);
s = _hsva_gets(data);
v = _hsva_getv(data);
data = GET_COLOR_DATA_HSV(color);
h = GET_DATA_C1(data);
s = GET_DATA_C2(data);
v = GET_DATA_C3(data);
hsv_to_rgb_int(&h, &s, &v);
c = makeacol_depth(depth, h, s, v, _hsva_geta(data));
c = makeacol_depth(depth, h, s, v, 255);
break;
}
case COLOR_TYPE_GRAY:
data = GET_COLOR_GRAY(color);
c = _graya_getv(data);
c = GET_COLOR_DATA_GRAY(color);
if (depth != 8)
c = makeacol_depth(depth, c, c, c, _graya_geta(data));
c = makeacol_depth(depth, c, c, c, 255);
break;
case COLOR_TYPE_INDEX:
c = GET_COLOR_INDEX(color);
c = GET_COLOR_DATA_INDEX(color);
if (depth != 8) {
ase_uint32 _c = palette_get_entry(get_current_palette(), c);
c = makeacol_depth(depth,
@ -629,57 +543,50 @@ int get_color_for_image(int imgtype, color_t color)
}
break;
case COLOR_TYPE_RGB:
data = GET_COLOR_RGB(color);
case COLOR_TYPE_RGB: {
int r, g, b;
data = GET_COLOR_DATA_RGB(color);
r = GET_DATA_C1(data);
g = GET_DATA_C2(data);
b = GET_DATA_C3(data);
switch (imgtype) {
case IMAGE_RGB:
c = data;
case IMAGE_RGB: {
c = _rgba(r, g, b, 255);
break;
}
case IMAGE_GRAYSCALE: {
int r = _rgba_getr(data);
int g = _rgba_getg(data);
int b = _rgba_getb(data);
rgb_to_hsv_int(&r, &g, &b);
c = _graya(b, _rgba_geta(data));
c = _graya(b, 255);
break;
}
case IMAGE_INDEXED:
c = orig_rgb_map->data
[_rgba_getr(data) >> 3]
[_rgba_getg(data) >> 3]
[_rgba_getb(data) >> 3];
c = orig_rgb_map->data[r >> 3][g >> 3][b >> 3];
break;
}
break;
}
case COLOR_TYPE_HSV: {
int h, s, v;
data = GET_COLOR_HSV(color);
data = GET_COLOR_DATA_HSV(color);
h = GET_DATA_C1(data);
s = GET_DATA_C2(data);
v = GET_DATA_C3(data);
switch (imgtype) {
case IMAGE_RGB:
h = _hsva_geth(data);
s = _hsva_gets(data);
v = _hsva_getv(data);
hsv_to_rgb_int(&h, &s, &v);
c = _rgba(h, s, v, _hsva_geta(data));
c = _rgba(h, s, v, 255);
break;
case IMAGE_GRAYSCALE: {
c = _graya(_hsva_getv(data),
_hsva_geta(data));
c = _graya(v, 255);
break;
}
case IMAGE_INDEXED:
h = _hsva_geth(data);
s = _hsva_gets(data);
v = _hsva_getv(data);
hsv_to_rgb_int(&h, &s, &v);
c = orig_rgb_map->data[h >> 3][s >> 3][v >> 3];
break;
}
@ -687,24 +594,24 @@ int get_color_for_image(int imgtype, color_t color)
}
case COLOR_TYPE_GRAY:
data = GET_COLOR_GRAY(color);
data = GET_COLOR_DATA_GRAY(color);
switch (imgtype) {
case IMAGE_RGB:
c = _graya_getv(data);
c = _rgba(c, c, c, _graya_geta(data));
c = data;
c = _rgba(c, c, c, 255);
break;
case IMAGE_GRAYSCALE:
c = data;
break;
case IMAGE_INDEXED:
c = _graya_getv(data);
c = orig_rgb_map->data[c>>3][c>>3][c>>3];
c = data;
c = orig_rgb_map->data[c >> 3][c >> 3][c >> 3];
break;
}
break;
case COLOR_TYPE_INDEX:
data = GET_COLOR_INDEX(color);
data = GET_COLOR_DATA_INDEX(color);
switch (imgtype) {
case IMAGE_RGB: {
ase_uint32 _c = palette_get_entry(get_current_palette(), data);
@ -749,69 +656,54 @@ void color_to_formalstring(int imgtype, color_t color,
break;
case COLOR_TYPE_RGB:
data = GET_COLOR_RGB(color);
data = GET_COLOR_DATA_RGB(color);
if (imgtype == IMAGE_GRAYSCALE) {
uszprintf(buf, size, "%s %d %s %d",
uszprintf(buf, size, "%s %d",
_("Gray"),
_graya_getv(get_color_for_image(imgtype, color)),
_("Alpha"),
_rgba_geta(data));
_graya_getv(get_color_for_image(imgtype, color)));
}
else {
uszprintf(buf, size, "%s %d %d %d",
_("RGB"),
_rgba_getr(data),
_rgba_getg(data),
_rgba_getb(data));
GET_DATA_C1(data),
GET_DATA_C2(data),
GET_DATA_C3(data));
if (imgtype == IMAGE_INDEXED)
uszprintf(buf+ustrlen(buf), size, " %s %d",
_("Index"), get_color_for_image(imgtype, color));
else if (imgtype == IMAGE_RGB)
uszprintf(buf+ustrlen(buf), size, " %s %d",
_("Alpha"), _rgba_geta(data));
}
break;
case COLOR_TYPE_HSV:
data = GET_COLOR_HSV(color);
data = GET_COLOR_DATA_HSV(color);
if (imgtype == IMAGE_GRAYSCALE) {
uszprintf(buf, size, "%s %d %s %d",
_("Gray"), _hsva_getv(data),
_("Alpha"), _hsva_geta(data));
uszprintf(buf, size, "%s %d",
_("Gray"), GET_DATA_C3(data));
}
else {
uszprintf(buf, size, "%s %d %d %d",
_("HSV"),
_hsva_geth(data),
_hsva_gets(data),
_hsva_getv(data));
GET_DATA_C1(data),
GET_DATA_C2(data),
GET_DATA_C3(data));
if (imgtype == IMAGE_INDEXED)
uszprintf(buf+ustrlen(buf), size, " %s %d",
_("Index"), get_color_for_image(imgtype, color));
else if (imgtype == IMAGE_RGB)
uszprintf(buf+ustrlen(buf), size, " %s %d",
_("Alpha"), _hsva_geta(data));
}
break;
case COLOR_TYPE_GRAY:
data = GET_COLOR_GRAY(color);
data = GET_COLOR_DATA_GRAY(color);
uszprintf(buf, size, "%s %d",
_("Gray"), _graya_getv(data));
if ((imgtype == IMAGE_RGB) ||
(imgtype == IMAGE_GRAYSCALE)) {
uszprintf(buf+ustrlen(buf), size, " %s %d",
_("Alpha"), _graya_geta(data));
}
_("Gray"), data);
break;
case COLOR_TYPE_INDEX: {
ase_uint32 _c = palette_get_entry(get_current_palette(), data & 0xff);
data = GET_COLOR_INDEX(color);
uszprintf(buf, size, "%s %d(RGB %d %d %d)",
data = GET_COLOR_DATA_INDEX(color);
uszprintf(buf, size, "%s %d (RGB %d %d %d)",
_("Index"),
data & 0xff,
_rgba_getr(_c),
@ -834,17 +726,17 @@ void color_to_formalstring(int imgtype, color_t color,
break;
case COLOR_TYPE_RGB:
data = GET_COLOR_RGB(color);
data = GET_COLOR_DATA_RGB(color);
if (imgtype == IMAGE_GRAYSCALE) {
uszprintf(buf, size, "KA %02x(%d)",
uszprintf(buf, size, "V %02x(%d)",
_graya_getv(get_color_for_image(imgtype, color)),
_graya_getv(get_color_for_image(imgtype, color)));
}
else {
uszprintf(buf, size, "RGB %02x%02x%02x",
_rgba_getr(data),
_rgba_getg(data),
_rgba_getb(data));
GET_DATA_C1(data),
GET_DATA_C2(data),
GET_DATA_C3(data));
if (imgtype == IMAGE_INDEXED)
uszprintf(buf+ustrlen(buf), size, "(%d)",
@ -853,17 +745,17 @@ void color_to_formalstring(int imgtype, color_t color,
break;
case COLOR_TYPE_HSV:
data = GET_COLOR_HSV(color);
data = GET_COLOR_DATA_HSV(color);
if (imgtype == IMAGE_GRAYSCALE) {
uszprintf(buf, size, "KA %02x(%d)",
_hsva_getv(data),
_hsva_getv(data));
uszprintf(buf, size, "V %02x(%d)",
GET_DATA_C3(data),
GET_DATA_C3(data));
}
else {
uszprintf(buf, size, "HSV %02x%02x%02x",
_hsva_geth(data),
_hsva_gets(data),
_hsva_getv(data));
GET_DATA_C1(data),
GET_DATA_C2(data),
GET_DATA_C3(data));
if (imgtype == IMAGE_INDEXED)
uszprintf(buf+ustrlen(buf), size, "(%d)",
@ -872,14 +764,12 @@ void color_to_formalstring(int imgtype, color_t color,
break;
case COLOR_TYPE_GRAY:
data = GET_COLOR_GRAY(color);
uszprintf(buf, size, "I %02x (%d)",
_graya_getv(data),
_graya_getv(data));
data = GET_COLOR_DATA_GRAY(color);
uszprintf(buf, size, "I %02x (%d)", data, data);
break;
case COLOR_TYPE_INDEX:
data = GET_COLOR_INDEX(color);
data = GET_COLOR_DATA_INDEX(color);
uszprintf(buf, size, "I %02x (%d)", data, data);
break;

View File

@ -32,13 +32,7 @@ enum {
COLOR_TYPE_INDEX,
};
typedef struct color_t
{
ase_uint32 coltype;
ase_uint32 imgcolor;
} color_t;
/* typedef uint64_t color_t; */
typedef uint32_t color_t;
char *color_to_string(color_t color, char *buf, int size);
color_t string_to_color(const char *str);
@ -47,9 +41,9 @@ int color_type(color_t color);
bool color_equals(color_t c1, color_t c2);
color_t color_mask(void);
color_t color_rgb(int r, int g, int b, int a);
color_t color_hsv(int h, int s, int v, int a);
color_t color_gray(int g, int a);
color_t color_rgb(int r, int g, int b);
color_t color_hsv(int h, int s, int v);
color_t color_gray(int g);
color_t color_index(int index);
int color_get_red(int imgtype, color_t color);
int color_get_green(int imgtype, color_t color);
@ -58,8 +52,6 @@ int color_get_hue(int imgtype, color_t color);
int color_get_saturation(int imgtype, color_t color);
int color_get_value(int imgtype, color_t color);
int color_get_index(int imgtype, color_t color);
int color_get_alpha(int imgtype, color_t color);
void color_set_alpha(color_t *color, int alpha);
color_t color_from_image(int imgtype, int c);
int blackandwhite(int r, int g, int b);

View File

@ -123,6 +123,18 @@ bool is_interactive(void)
return ase_mode & MODE_GUI ? TRUE: FALSE;
}
char *get_pretty_memsize(unsigned int memsize, char *buf, unsigned int bufsize)
{
if (memsize < 1000)
uszprintf(buf, bufsize, "%d bytes", memsize);
else if (memsize < 1000*1000)
uszprintf(buf, bufsize, "%0.1fK", memsize/1024.0f);
else
uszprintf(buf, bufsize, "%0.1fM", memsize/(1024.0f*1024.0f));
return buf;
}
/**
* Like 'strerror' but thread-safe.
*

View File

@ -36,6 +36,7 @@ void core_exit(void);
void verbose_printf(const char *format, ...);
bool is_interactive(void);
char *get_pretty_memsize(unsigned int memsize, char *buf, unsigned int bufsize);
char *get_errno_string(int errnum, char *buf, int size);
#endif /* CORE_H */

View File

@ -171,6 +171,7 @@ Image *RenderText(const char *fontname, int size, int color, const char *text)
static Image *render_text(FONT *f, const char *text, int color)
{
/* TODO warning this uses Image->dat and not Image->line */
#define DO(type, colfunc) \
{ \
register int c; \

View File

@ -326,7 +326,7 @@ static bool layer_box_msg_proc(JWidget widget, JMessage msg)
makecol(255, 255, 255): makecol(0, 0, 0));
#else
{
int tabs = -2;
int tx, tabs = -2;
Layer *l = layer;
while (l != NULL) {
@ -342,10 +342,20 @@ static bool layer_box_msg_proc(JWidget widget, JMessage msg)
/* draw the layer name */
textout(bmp, widget->text_font, layer->name,
2+8+2+8+2+8+tabs*16,
tx = 2+8+2+8+2+8+tabs*16,
y_mid-text_height(widget->text_font)/2,
selected_layer ?
makecol(255, 255, 255): makecol(0, 0, 0));
/* the background should be underlined */
if (layer_is_background(layer)) {
hline(bmp,
tx,
y_mid-text_height(widget->text_font)/2+text_height(widget->text_font)+1,
tx+text_length(widget->text_font, layer->name),
selected_layer ?
makecol(255, 255, 255): makecol(0, 0, 0));
}
}
#endif
y += h;
@ -416,7 +426,7 @@ static bool layer_box_msg_proc(JWidget widget, JMessage msg)
if (msg->any.shifts & KB_SHIFT_FLAG ||
msg->mouse.middle) {
state = STATE_SCROLLING;
jmouse_set_cursor(JI_CURSOR_MOVE);
jmouse_set_cursor(JI_CURSOR_SCROLL);
}
else {
select_layer_motion(widget, layer_box, layer_box->cel_box);
@ -427,17 +437,17 @@ static bool layer_box_msg_proc(JWidget widget, JMessage msg)
/* toggle icon status (eye or the padlock) */
if (msg->mouse.x < 2+8+2+8+2) {
if (msg->mouse.x <= 2+8+1) {
layer_box->layer->readable = !layer_box->layer->readable;
layer_box->layer->flags ^= LAYER_IS_READABLE;
}
else {
layer_box->layer->writable = !layer_box->layer->writable;
layer_box->layer->flags ^= LAYER_IS_WRITABLE;
}
jwidget_dirty(widget);
}
/* move */
else {
state = STATE_MOVING;
jmouse_set_cursor(JI_CURSOR_MOVE);
jmouse_set_cursor(JI_CURSOR_SCROLL);
}
}
@ -706,7 +716,7 @@ static bool cel_box_msg_proc(JWidget widget, JMessage msg)
if (msg->any.shifts & KB_SHIFT_FLAG) {
state = STATE_SCROLLING;
jmouse_set_cursor(JI_CURSOR_MOVE);
jmouse_set_cursor(JI_CURSOR_SCROLL);
}
else {
Cel *cel;
@ -723,7 +733,7 @@ static bool cel_box_msg_proc(JWidget widget, JMessage msg)
current_sprite->frame);
if (cel) {
state = STATE_MOVING; /* now we will moving a cel */
jmouse_set_cursor(JI_CURSOR_MOVE);
jmouse_set_cursor(JI_CURSOR_SCROLL);
cel_box->layer = current_sprite->layer;
cel_box->cel = cel;

View File

@ -48,7 +48,9 @@ void dialogs_options(void)
JWidget window, check_smooth, check_dither;
JWidget button_ok;
JWidget move_click2, draw_click2, killer;
JWidget undo_size_limit;
int x, y, old_x, old_y;
char buf[512];
x = get_config_int("Options", "MouseX", 6);
y = get_config_int("Options", "MouseY", 6);
@ -70,6 +72,7 @@ void dialogs_options(void)
"dither", &check_dither,
"move_click2", &move_click2,
"draw_click2", &draw_click2,
"undo_size_limit", &undo_size_limit,
"button_ok", &button_ok, NULL)) {
jwidget_free(window);
return;
@ -90,6 +93,9 @@ void dialogs_options(void)
if (get_config_bool("Options", "Dither", FALSE))
jwidget_select(check_dither);
uszprintf(buf, sizeof(buf), "%d", get_config_int("Options", "UndoSizeLimit", 8));
jwidget_set_text(undo_size_limit, buf);
HOOK(slider_x, JI_SIGNAL_SLIDER_CHANGE, slider_mouse_hook, NULL);
HOOK(slider_y, JI_SIGNAL_SLIDER_CHANGE, slider_mouse_hook, NULL);
@ -97,16 +103,22 @@ void dialogs_options(void)
killer = jwindow_get_killer(window);
if (killer == button_ok) {
int undo_size_limit_value;
set_config_bool("Options", "LockMouse", jwidget_is_selected(check_lockmouse));
set_config_bool("Options", "MoveSmooth", jwidget_is_selected(check_smooth));
set_config_bool("Options", "MoveClick2", jwidget_is_selected(move_click2));
set_config_bool("Options", "DrawClick2", jwidget_is_selected(draw_click2));
if (get_config_bool("Options", "Dither", FALSE) != jwidget_is_selected(check_dither)) {
set_config_bool("Options", "Dither", jwidget_is_selected(check_dither));
refresh_all_editors();
}
undo_size_limit_value = ustrtol(jwidget_get_text(undo_size_limit), NULL, 10);
undo_size_limit_value = MID(1, undo_size_limit_value, 9999);
set_config_int("Options", "UndoSizeLimit", undo_size_limit_value);
/* save configuration */
flush_config_file();
}

View File

@ -88,14 +88,14 @@ static void do_quick(int action)
sprite->mask->x-x + sprite->mask->w-1,
sprite->mask->y-y + sprite->mask->h-1);
dirty_get(dirty);
dirty_save_image_data(dirty);
}
/* clear the mask region */
if (action == ACTION_MOVE) {
int enabled = undo_is_enabled(sprite->undo);
undo_disable(sprite->undo);
ClearMask(color_mask());
ClearMask();
if (enabled)
undo_enable(sprite->undo);
}
@ -134,10 +134,10 @@ static void do_quick(int action)
dirty_rectfill(dirty, u-x, v-y,
u-x + src->w-1,
v-y + src->h-1);
dirty_get(dirty);
dirty_save_image_data(dirty);
/* put the first cleared part */
dirty_put(dirty_copy);
dirty_restore_image_data(dirty_copy);
dirty_free(dirty_copy);
switch (action) {
@ -174,7 +174,7 @@ static void do_quick(int action)
/* user cancels the operation */
else {
/* restore the "dst" image */
dirty_put(dirty);
dirty_restore_image_data(dirty);
/* restore the mask */
sprite_set_mask(sprite, mask_backup);

View File

@ -54,7 +54,6 @@ typedef struct ASE_Header
ase_uint16 speed; /* deprecated, use "duration" of FrameHeader */
ase_uint32 next;
ase_uint32 frit;
ase_uint8 bgcolor[4];
} ASE_Header;
typedef struct ASE_FrameHeader
@ -157,23 +156,6 @@ static bool load_ASE(FileOp *fop)
sprite_set_frames(sprite, header.frames);
sprite_set_speed(sprite, header.speed);
/* set background color */
switch (sprite->imgtype) {
case IMAGE_RGB:
sprite_set_bgcolor(sprite, _rgba(header.bgcolor[0],
header.bgcolor[1],
header.bgcolor[2],
header.bgcolor[3]));
break;
case IMAGE_GRAYSCALE:
sprite_set_bgcolor(sprite, _graya(header.bgcolor[0],
header.bgcolor[1]));
break;
case IMAGE_INDEXED:
sprite_set_bgcolor(sprite, header.bgcolor[0]);
break;
}
/* prepare variables for layer chunks */
last_layer = sprite->set;
current_level = -1;
@ -378,10 +360,6 @@ static bool ase_file_read_header(FILE *f, ASE_Header *header)
header->speed = fgetw(f);
header->next = fgetl(f);
header->frit = fgetl(f);
header->bgcolor[0] = fgetc(f);
header->bgcolor[1] = fgetc(f);
header->bgcolor[2] = fgetc(f);
header->bgcolor[3] = fgetc(f);
fseek(f, header->pos+128, SEEK_SET);
return TRUE;
@ -403,26 +381,6 @@ static void ase_file_prepare_header(FILE *f, ASE_Header *header, Sprite *sprite)
header->speed = sprite_get_frlen(sprite, 0);
header->next = 0;
header->frit = 0;
header->bgcolor[0] = 0;
header->bgcolor[1] = 0;
header->bgcolor[2] = 0;
header->bgcolor[3] = 0;
switch (sprite->imgtype) {
case IMAGE_RGB:
header->bgcolor[0] = _rgba_getr(sprite->bgcolor);
header->bgcolor[1] = _rgba_getg(sprite->bgcolor);
header->bgcolor[2] = _rgba_getb(sprite->bgcolor);
header->bgcolor[3] = _rgba_geta(sprite->bgcolor);
break;
case IMAGE_GRAYSCALE:
header->bgcolor[0] = _graya_getv(sprite->bgcolor);
header->bgcolor[1] = _graya_geta(sprite->bgcolor);
break;
case IMAGE_INDEXED:
header->bgcolor[0] = sprite->bgcolor;
break;
}
fseek(f, header->pos+128, SEEK_SET);
}
@ -443,10 +401,6 @@ static void ase_file_write_header(FILE *f, ASE_Header *header)
fputw(header->speed, f);
fputl(header->next, f);
fputl(header->frit, f);
fputc(header->bgcolor[0], f);
fputc(header->bgcolor[1], f);
fputc(header->bgcolor[2], f);
fputc(header->bgcolor[3], f);
ase_file_write_padding(f, 96);
@ -703,8 +657,7 @@ static Layer *ase_file_read_layer_chunk(FILE *f, Sprite *sprite, Layer **previou
if (layer) {
/* flags */
layer->readable = (flags & 1) ? TRUE: FALSE;
layer->writable = (flags & 2) ? TRUE: FALSE;
layer->flags = flags;
/* name */
if (name) {
@ -736,7 +689,7 @@ static void ase_file_write_layer_chunk(FILE *f, Layer *layer)
ase_file_write_start_chunk(f, ASE_FILE_CHUNK_LAYER);
/* flags */
fputw((layer->readable & 1) | ((layer->writable & 1) << 1), f);
fputw(layer->flags, f);
/* layer type */
fputw(layer_is_image(layer) ? 0:

View File

@ -23,6 +23,7 @@
#include <allegro/color.h>
#include "file/file.h"
#include "file/filedata.h"
#include "raster/raster.h"
static bool load_BMP(FileOp *fop);
@ -50,11 +51,11 @@ FileFormat format_bmp =
typedef struct BITMAPFILEHEADER
{
ase_uint32 bfType;
ase_uint32 bfSize;
ase_uint16 bfReserved1;
ase_uint16 bfReserved2;
ase_uint32 bfOffBits;
ase_uint32 bfType;
ase_uint32 bfSize;
ase_uint16 bfReserved1;
ase_uint16 bfReserved2;
ase_uint32 bfOffBits;
} BITMAPFILEHEADER;
/* Used for both OS/2 and Windows BMP.
@ -62,32 +63,32 @@ typedef struct BITMAPFILEHEADER
*/
typedef struct BITMAPINFOHEADER
{
ase_uint32 biWidth;
ase_uint32 biHeight;
ase_uint16 biBitCount;
ase_uint32 biCompression;
ase_uint32 biWidth;
ase_uint32 biHeight;
ase_uint16 biBitCount;
ase_uint32 biCompression;
} BITMAPINFOHEADER;
typedef struct WINBMPINFOHEADER /* size: 40 */
{
ase_uint32 biWidth;
ase_uint32 biHeight;
ase_uint16 biPlanes;
ase_uint16 biBitCount;
ase_uint32 biCompression;
ase_uint32 biSizeImage;
ase_uint32 biXPelsPerMeter;
ase_uint32 biYPelsPerMeter;
ase_uint32 biClrUsed;
ase_uint32 biClrImportant;
ase_uint32 biWidth;
ase_uint32 biHeight;
ase_uint16 biPlanes;
ase_uint16 biBitCount;
ase_uint32 biCompression;
ase_uint32 biSizeImage;
ase_uint32 biXPelsPerMeter;
ase_uint32 biYPelsPerMeter;
ase_uint32 biClrUsed;
ase_uint32 biClrImportant;
} WINBMPINFOHEADER;
typedef struct OS2BMPINFOHEADER /* size: 12 */
{
ase_uint16 biWidth;
ase_uint16 biHeight;
ase_uint16 biPlanes;
ase_uint16 biBitCount;
ase_uint16 biWidth;
ase_uint16 biHeight;
ase_uint16 biPlanes;
ase_uint16 biBitCount;
} OS2BMPINFOHEADER;
/* read_bmfileheader:
@ -95,16 +96,16 @@ typedef struct OS2BMPINFOHEADER /* size: 12 */
*/
static int read_bmfileheader(FILE *f, BITMAPFILEHEADER *fileheader)
{
fileheader->bfType = fgetw(f);
fileheader->bfSize= fgetl(f);
fileheader->bfReserved1= fgetw(f);
fileheader->bfReserved2= fgetw(f);
fileheader->bfOffBits= fgetl(f);
fileheader->bfType = fgetw(f);
fileheader->bfSize = fgetl(f);
fileheader->bfReserved1 = fgetw(f);
fileheader->bfReserved2 = fgetw(f);
fileheader->bfOffBits = fgetl(f);
if (fileheader->bfType != 19778)
return -1;
if (fileheader->bfType != 19778)
return -1;
return 0;
return 0;
}
/* read_win_bminfoheader:
@ -112,25 +113,25 @@ static int read_bmfileheader(FILE *f, BITMAPFILEHEADER *fileheader)
*/
static int read_win_bminfoheader(FILE *f, BITMAPINFOHEADER *infoheader)
{
WINBMPINFOHEADER win_infoheader;
WINBMPINFOHEADER win_infoheader;
win_infoheader.biWidth = fgetl(f);
win_infoheader.biHeight = fgetl(f);
win_infoheader.biPlanes = fgetw(f);
win_infoheader.biBitCount = fgetw(f);
win_infoheader.biCompression = fgetl(f);
win_infoheader.biSizeImage = fgetl(f);
win_infoheader.biXPelsPerMeter = fgetl(f);
win_infoheader.biYPelsPerMeter = fgetl(f);
win_infoheader.biClrUsed = fgetl(f);
win_infoheader.biClrImportant = fgetl(f);
win_infoheader.biWidth = fgetl(f);
win_infoheader.biHeight = fgetl(f);
win_infoheader.biPlanes = fgetw(f);
win_infoheader.biBitCount = fgetw(f);
win_infoheader.biCompression = fgetl(f);
win_infoheader.biSizeImage = fgetl(f);
win_infoheader.biXPelsPerMeter = fgetl(f);
win_infoheader.biYPelsPerMeter = fgetl(f);
win_infoheader.biClrUsed = fgetl(f);
win_infoheader.biClrImportant = fgetl(f);
infoheader->biWidth = win_infoheader.biWidth;
infoheader->biHeight = win_infoheader.biHeight;
infoheader->biBitCount = win_infoheader.biBitCount;
infoheader->biCompression = win_infoheader.biCompression;
infoheader->biWidth = win_infoheader.biWidth;
infoheader->biHeight = win_infoheader.biHeight;
infoheader->biBitCount = win_infoheader.biBitCount;
infoheader->biCompression = win_infoheader.biCompression;
return 0;
return 0;
}
/* read_os2_bminfoheader:
@ -138,36 +139,46 @@ static int read_win_bminfoheader(FILE *f, BITMAPINFOHEADER *infoheader)
*/
static int read_os2_bminfoheader(FILE *f, BITMAPINFOHEADER *infoheader)
{
OS2BMPINFOHEADER os2_infoheader;
OS2BMPINFOHEADER os2_infoheader;
os2_infoheader.biWidth = fgetw(f);
os2_infoheader.biHeight = fgetw(f);
os2_infoheader.biPlanes = fgetw(f);
os2_infoheader.biBitCount = fgetw(f);
os2_infoheader.biWidth = fgetw(f);
os2_infoheader.biHeight = fgetw(f);
os2_infoheader.biPlanes = fgetw(f);
os2_infoheader.biBitCount = fgetw(f);
infoheader->biWidth = os2_infoheader.biWidth;
infoheader->biHeight = os2_infoheader.biHeight;
infoheader->biBitCount = os2_infoheader.biBitCount;
infoheader->biCompression = 0;
infoheader->biWidth = os2_infoheader.biWidth;
infoheader->biHeight = os2_infoheader.biHeight;
infoheader->biBitCount = os2_infoheader.biBitCount;
infoheader->biCompression = 0;
return 0;
return 0;
}
/* read_bmicolors:
* Loads the color palette for 1,4,8 bit formats.
*/
static void read_bmicolors(FileOp *fop, int ncols, FILE *f,int win_flag)
static void read_bmicolors(FileOp *fop, int bytes, FILE *f, bool win_flag)
{
int i, r, g, b;
int i, j, r, g, b;
for (i=0; i<ncols; i++) {
b = fgetc(f);
g = fgetc(f);
r = fgetc(f);
fop_sequence_set_color(fop, i, r, g, b);
if (win_flag)
fgetc(f);
}
for (i=j=0; i+3 <= bytes && j < MAX_PALETTE_COLORS; ) {
b = fgetc(f);
g = fgetc(f);
r = fgetc(f);
fop_sequence_set_color(fop, j, r, g, b);
j++;
i += 3;
if (win_flag && i < bytes) {
fgetc(f);
i++;
}
}
for (; i<bytes; i++)
fgetc(f);
}
/* read_1bit_line:
@ -175,28 +186,28 @@ static void read_bmicolors(FileOp *fop, int ncols, FILE *f,int win_flag)
*/
static void read_1bit_line(int length, FILE *f, Image *image, int line)
{
unsigned char b[32];
unsigned long n;
int i, j, k;
int pix;
unsigned char b[32];
unsigned long n;
int i, j, k;
int pix;
for (i=0; i<length; i++) {
j = i % 32;
if (j == 0) {
n = fgetl(f);
n =
((n&0x000000ff)<<24) |
((n&0x0000ff00)<< 8) |
((n&0x00ff0000)>> 8) |
((n&0xff000000)>>24);
for (k=0; k<32; k++) {
b[31-k] = (char)(n & 1);
n = n >> 1;
}
for (i=0; i<length; i++) {
j = i % 32;
if (j == 0) {
n = fgetl(f);
n =
((n&0x000000ff)<<24) |
((n&0x0000ff00)<< 8) |
((n&0x00ff0000)>> 8) |
((n&0xff000000)>>24);
for (k=0; k<32; k++) {
b[31-k] = (char)(n & 1);
n = n >> 1;
}
pix = b[j];
image_putpixel(image, i, line, pix);
}
}
pix = b[j];
image_putpixel(image, i, line, pix);
}
}
/* read_4bit_line:
@ -204,27 +215,27 @@ static void read_1bit_line(int length, FILE *f, Image *image, int line)
*/
static void read_4bit_line(int length, FILE *f, Image *image, int line)
{
unsigned char b[8];
unsigned long n;
int i, j, k;
int temp;
int pix;
unsigned char b[8];
unsigned long n;
int i, j, k;
int temp;
int pix;
for (i=0; i<length; i++) {
j = i % 8;
if (j == 0) {
n = fgetl(f);
for (k=0; k<4; k++) {
temp = n & 255;
b[k*2+1] = temp & 15;
temp = temp >> 4;
b[k*2] = temp & 15;
n = n >> 8;
}
for (i=0; i<length; i++) {
j = i % 8;
if (j == 0) {
n = fgetl(f);
for (k=0; k<4; k++) {
temp = n & 255;
b[k*2+1] = temp & 15;
temp = temp >> 4;
b[k*2] = temp & 15;
n = n >> 8;
}
pix = b[j];
image_putpixel(image, i, line, pix);
}
}
pix = b[j];
image_putpixel(image, i, line, pix);
}
}
/* read_8bit_line:
@ -232,48 +243,76 @@ static void read_4bit_line(int length, FILE *f, Image *image, int line)
*/
static void read_8bit_line(int length, FILE *f, Image *image, int line)
{
unsigned char b[4];
unsigned long n;
int i, j, k;
int pix;
unsigned char b[4];
unsigned long n;
int i, j, k;
int pix;
for (i=0; i<length; i++) {
j = i % 4;
if (j == 0) {
n = fgetl(f);
for (k=0; k<4; k++) {
b[k] = (char)(n & 255);
n = n >> 8;
}
for (i=0; i<length; i++) {
j = i % 4;
if (j == 0) {
n = fgetl(f);
for (k=0; k<4; k++) {
b[k] = (char)(n & 255);
n = n >> 8;
}
pix = b[j];
image_putpixel(image, i, line, pix);
}
}
pix = b[j];
image_putpixel(image, i, line, pix);
}
}
static void read_16bit_line(int length, FILE *f, Image *image, int line)
{
int i, r, g, b, word;
for (i=0; i<length; i++) {
word = fgetw(f);
r = (word >> 10) & 0x1f;
g = (word >> 5) & 0x1f;
b = (word) & 0x1f;
image_putpixel(image, i, line,
_rgba(_rgb_scale_5[r],
_rgb_scale_5[g],
_rgb_scale_5[b], 255));
}
i = (2*i) % 4;
if (i > 0)
while (i++ < 4)
fgetc(f);
}
/* read_24bit_line:
* Support function for reading the 24 bit bitmap file format, doing
* our best to convert it down to a 256 color palette.
*/
static void read_24bit_line(int length, FILE *f, Image *image, int line)
{
int i, nbytes;
RGB c;
int i, r, g, b;
nbytes=0;
for (i=0; i<length; i++) {
b = fgetc(f);
g = fgetc(f);
r = fgetc(f);
image_putpixel(image, i, line, _rgba(r, g, b, 255));
}
for (i=0; i<length; i++) {
c.b = fgetc(f);
c.g = fgetc(f);
c.r = fgetc(f);
image_putpixel(image, i, line, _rgba(c.r, c.g, c.b, 255));
nbytes += 3;
}
i = (3*i) % 4;
if (i > 0)
while (i++ < 4)
fgetc(f);
}
nbytes = nbytes % 4;
if (nbytes != 0)
for (i=nbytes; i<4; i++)
fgetc(f);
static void read_32bit_line(int length, FILE *f, Image *image, int line)
{
int i, r, g, b;
for (i=0; i<length; i++) {
b = fgetc(f);
g = fgetc(f);
r = fgetc(f);
fgetc(f);
image_putpixel(image, i, line, _rgba(r, g, b, 255));
}
}
/* read_image:
@ -281,234 +320,261 @@ static void read_24bit_line(int length, FILE *f, Image *image, int line)
*/
static void read_image(FILE *f, Image *image, AL_CONST BITMAPINFOHEADER *infoheader, FileOp *fop)
{
int i, line;
int i, line, height, dir;
for (i=0; i<(int)infoheader->biHeight; i++) {
line = i;
height = (int)infoheader->biHeight;
line = height < 0 ? 0: height-1;
dir = height < 0 ? 1: -1;
height = ABS(height);
switch (infoheader->biBitCount) {
for (i=0; i<height; i++, line+=dir) {
switch (infoheader->biBitCount) {
case 1: read_1bit_line(infoheader->biWidth, f, image, line); break;
case 4: read_4bit_line(infoheader->biWidth, f, image, line); break;
case 8: read_8bit_line(infoheader->biWidth, f, image, line); break;
case 16: read_16bit_line(infoheader->biWidth, f, image, line); break;
case 24: read_24bit_line(infoheader->biWidth, f, image, line); break;
case 32: read_32bit_line(infoheader->biWidth, f, image, line); break;
}
case 1:
read_1bit_line(infoheader->biWidth, f, image, infoheader->biHeight-i-1);
break;
case 4:
read_4bit_line(infoheader->biWidth, f, image, infoheader->biHeight-i-1);
break;
case 8:
read_8bit_line(infoheader->biWidth, f, image, infoheader->biHeight-i-1);
break;
case 24:
read_24bit_line(infoheader->biWidth, f, image, infoheader->biHeight-i-1);
break;
}
fop_progress(fop, (float)(i+1) / (float)(infoheader->biHeight));
if (fop_is_stop(fop))
break;
}
fop_progress(fop, (float)(i+1) / (float)(height));
if (fop_is_stop(fop))
break;
}
}
/* read_RLE8_compressed_image:
/* read_rle8_compressed_image:
* For reading the 8 bit RLE compressed BMP image format.
*
* @note This support compressed top-down bitmaps, the MSDN says that
* they can't exist, but Photoshop can create them.
*/
static void read_RLE8_compressed_image(FILE *f, Image *image, AL_CONST BITMAPINFOHEADER *infoheader)
static void read_rle8_compressed_image(FILE *f, Image *image, AL_CONST BITMAPINFOHEADER *infoheader)
{
unsigned char count, val, val0;
int j, pos, line;
int eolflag, eopicflag;
unsigned char count, val, val0;
int j, pos, line, height, dir;
int eolflag, eopicflag;
eopicflag = 0;
eopicflag = 0;
line = infoheader->biHeight - 1;
height = (int)infoheader->biHeight;
line = height < 0 ? 0: height-1;
dir = height < 0 ? 1: -1;
height = ABS(height);
while (eopicflag == 0) {
pos = 0; /* x position in bitmap */
eolflag = 0; /* end of line flag */
while (eopicflag == 0) {
pos = 0; /* x position in bitmap */
eolflag = 0; /* end of line flag */
while ((eolflag == 0) && (eopicflag == 0)) {
count = fgetc(f);
val = fgetc(f);
while ((eolflag == 0) && (eopicflag == 0)) {
count = fgetc(f);
val = fgetc(f);
if (count > 0) { /* repeat pixel count times */
for (j=0;j<count;j++) {
image_putpixel(image, pos, line, val);
pos++;
}
}
else {
switch (val) {
case 0: /* end of line flag */
eolflag=1;
break;
case 1: /* end of picture flag */
eopicflag=1;
break;
case 2: /* displace picture */
count = fgetc(f);
val = fgetc(f);
pos += count;
line -= val;
break;
default: /* read in absolute mode */
for (j=0; j<val; j++) {
val0 = fgetc(f);
image_putpixel(image, pos, line, val0);
pos++;
}
if (j%2 == 1)
val0 = fgetc(f); /* align on word boundary */
break;
}
}
if (pos-1 > (int)infoheader->biWidth)
eolflag=1;
}
line--;
if (line < 0)
eopicflag = 1;
}
}
/* read_RLE4_compressed_image:
* For reading the 4 bit RLE compressed BMP image format.
*/
static void read_RLE4_compressed_image(FILE *f, Image *image, AL_CONST BITMAPINFOHEADER *infoheader)
{
unsigned char b[8];
unsigned char count;
unsigned short val0, val;
int j, k, pos, line;
int eolflag, eopicflag;
eopicflag = 0; /* end of picture flag */
line = infoheader->biHeight - 1;
while (eopicflag == 0) {
pos = 0;
eolflag = 0; /* end of line flag */
while ((eolflag == 0) && (eopicflag == 0)) {
count = fgetc(f);
val = fgetc(f);
if (count > 0) { /* repeat pixels count times */
b[1] = val & 15;
b[0] = (val >> 4) & 15;
for (j=0; j<count; j++) {
image_putpixel(image, pos, line, b[j%2]);
pos++;
}
}
else {
switch (val) {
case 0: /* end of line */
eolflag=1;
break;
case 1: /* end of picture */
eopicflag=1;
break;
case 2: /* displace image */
count = fgetc(f);
val = fgetc(f);
pos += count;
line -= val;
break;
default: /* read in absolute mode */
for (j=0; j<val; j++) {
if ((j%4) == 0) {
val0 = fgetw(f);
for (k=0; k<2; k++) {
b[2*k+1] = val0 & 15;
val0 = val0 >> 4;
b[2*k] = val0 & 15;
val0 = val0 >> 4;
}
}
image_putpixel(image, pos, line, b[j%4]);
pos++;
}
break;
}
}
if (pos-1 > (int)infoheader->biWidth)
eolflag=1;
}
line--;
if (line < 0)
eopicflag = 1;
}
}
static void read_bitfields_image(FILE *f, Image *image, int bpp, BITMAPINFOHEADER *infoheader)
{
int k, i;
int bytesPerPixel;
int red, grn, blu;
unsigned long buffer;
if (bpp == 15)
bytesPerPixel = 2;
else
bytesPerPixel = bpp / 8;
for (i=0; i<(int)infoheader->biHeight; i++) {
for (k=0; k<(int)infoheader->biWidth; k++) {
fread(&buffer, 1, bytesPerPixel, f);
if (bpp == 15) {
red = (buffer >> 10) & 0x1f;
grn = (buffer >> 5) & 0x1f;
blu = (buffer) & 0x1f;
buffer = _rgba(_rgb_scale_5[red],
_rgb_scale_5[grn],
_rgb_scale_5[blu], 255);
}
else if (bpp == 16) {
red = (buffer >> 11) & 0x1f;
grn = (buffer >> 5) & 0x3f;
blu = (buffer) & 0x1f;
buffer = _rgba(_rgb_scale_5[red],
_rgb_scale_6[grn],
_rgb_scale_5[blu], 255);
if (count > 0) { /* repeat pixel count times */
for (j=0;j<count;j++) {
image_putpixel(image, pos, line, val);
pos++;
}
}
else {
red = (buffer >> 16) & 0xff;
grn = (buffer >> 8) & 0xff;
blu = (buffer) & 0xff;
buffer = _rgba(red, grn, blu, 255);
switch (val) {
case 0: /* end of line flag */
eolflag=1;
break;
case 1: /* end of picture flag */
eopicflag=1;
break;
case 2: /* displace picture */
count = fgetc(f);
val = fgetc(f);
pos += count;
line += val*dir;
break;
default: /* read in absolute mode */
for (j=0; j<val; j++) {
val0 = fgetc(f);
image_putpixel(image, pos, line, val0);
pos++;
}
if (j%2 == 1)
val0 = fgetc(f); /* align on word boundary */
break;
}
}
image->method->putpixel(image,
k, (infoheader->biHeight - i) - 1, buffer);
if (pos-1 > (int)infoheader->biWidth)
eolflag=1;
}
line += dir;
if (line < 0 || line >= height)
eopicflag = 1;
}
}
/* read_rle4_compressed_image:
* For reading the 4 bit RLE compressed BMP image format.
*
* @note This support compressed top-down bitmaps, the MSDN says that
* they can't exist, but Photoshop can create them.
*/
static void read_rle4_compressed_image(FILE *f, Image *image, AL_CONST BITMAPINFOHEADER *infoheader)
{
unsigned char b[8];
unsigned char count;
unsigned short val0, val;
int j, k, pos, line, height, dir;
int eolflag, eopicflag;
eopicflag = 0; /* end of picture flag */
height = (int)infoheader->biHeight;
line = height < 0 ? 0: height-1;
dir = height < 0 ? 1: -1;
height = ABS(height);
while (eopicflag == 0) {
pos = 0;
eolflag = 0; /* end of line flag */
while ((eolflag == 0) && (eopicflag == 0)) {
count = fgetc(f);
val = fgetc(f);
if (count > 0) { /* repeat pixels count times */
b[1] = val & 15;
b[0] = (val >> 4) & 15;
for (j=0; j<count; j++) {
image_putpixel(image, pos, line, b[j%2]);
pos++;
}
}
else {
switch (val) {
case 0: /* end of line */
eolflag=1;
break;
case 1: /* end of picture */
eopicflag=1;
break;
case 2: /* displace image */
count = fgetc(f);
val = fgetc(f);
pos += count;
line += val*dir;
break;
default: /* read in absolute mode */
for (j=0; j<val; j++) {
if ((j%4) == 0) {
val0 = fgetw(f);
for (k=0; k<2; k++) {
b[2*k+1] = val0 & 15;
val0 = val0 >> 4;
b[2*k] = val0 & 15;
val0 = val0 >> 4;
}
}
image_putpixel(image, pos, line, b[j%4]);
pos++;
}
break;
}
}
if (pos-1 > (int)infoheader->biWidth)
eolflag=1;
}
line += dir;
if (line < 0 || line >= height)
eopicflag = 1;
}
}
static int read_bitfields_image(FILE *f, Image *image, BITMAPINFOHEADER *infoheader,
unsigned long rmask, unsigned long gmask, unsigned long bmask)
{
#define CALC_SHIFT(c) \
mask = ~c##mask; \
c##shift = 0; \
while (mask & 1) { \
++c##shift; \
mask >>= 1; \
} \
if ((c##mask >> c##shift) == 0x1f) \
c##scale = _rgb_scale_5; \
else if ((c##mask >> c##shift) == 0x3f) \
c##scale = _rgb_scale_6; \
else \
c##scale = NULL;
unsigned long buffer, mask, rshift, gshift, bshift;
int i, j, k, line, height, dir, r, g, b;
int *rscale, *gscale, *bscale;
int bits_per_pixel;
int bytes_per_pixel;
height = (int)infoheader->biHeight;
line = height < 0 ? 0: height-1;
dir = height < 0 ? 1: -1;
height = ABS(height);
/* calculate shifts */
CALC_SHIFT(r);
CALC_SHIFT(g);
CALC_SHIFT(b);
/* calculate bits-per-pixel and bytes-per-pixel */
bits_per_pixel = infoheader->biBitCount;
bytes_per_pixel = ((bits_per_pixel / 8) +
((bits_per_pixel % 8) > 0 ? 1: 0));
for (i=0; i<height; i++, line+=dir) {
for (j=0; j<(int)infoheader->biWidth; j++) {
/* read the DWORD, WORD or BYTE in little-endian order */
buffer = 0;
for (k=0; k<bytes_per_pixel; k++)
buffer |= fgetc(f) << (k<<3);
r = (buffer & rmask) >> rshift;
g = (buffer & gmask) >> gshift;
b = (buffer & bmask) >> bshift;
r = rscale ? rscale[r]: r;
g = gscale ? gscale[g]: g;
b = bscale ? bscale[b]: b;
image->method->putpixel(image, j, line, _rgba(r, g, b, 255));
}
j = (bytes_per_pixel*j) % 4;
if (j > 0)
while (j++ < 4)
fgetc(f);
}
return 0;
}
static bool load_BMP(FileOp *fop)
{
unsigned long rmask, gmask, bmask;
BITMAPFILEHEADER fileheader;
BITMAPINFOHEADER infoheader;
Image *image;
FILE *f;
int ncol;
unsigned long biSize;
int type, bpp = 0;
int type, format;
f = fopen(fop->filename, "rb");
if (!f)
@ -522,60 +588,50 @@ static bool load_BMP(FileOp *fop)
biSize = fgetl(f);
if (biSize == WININFOHEADERSIZE) {
format = BMPDATA_FORMAT_WINDOWS;
if (read_win_bminfoheader(f, &infoheader) != 0) {
fclose(f);
return FALSE;
}
/* compute number of colors recorded */
ncol = (fileheader.bfOffBits - 54) / 4;
if (infoheader.biCompression != BI_BITFIELDS)
read_bmicolors(fop, ncol, f, 1);
read_bmicolors(fop, fileheader.bfOffBits - 54, f, TRUE);
}
else if (biSize == OS2INFOHEADERSIZE) {
format = BMPDATA_FORMAT_OS2;
if (read_os2_bminfoheader(f, &infoheader) != 0) {
fclose(f);
return FALSE;
}
/* compute number of colors recorded */
ncol = (fileheader.bfOffBits - 26) / 3;
if (infoheader.biCompression != BI_BITFIELDS)
read_bmicolors(fop, ncol, f, 0);
read_bmicolors(fop, fileheader.bfOffBits - 26, f, FALSE);
}
else {
fclose(f);
return FALSE;
}
if ((infoheader.biBitCount == 24) || (infoheader.biBitCount == 16))
if ((infoheader.biBitCount == 32) ||
(infoheader.biBitCount == 24) ||
(infoheader.biBitCount == 16))
type = IMAGE_RGB;
else
type = IMAGE_INDEXED;
/* bitfields have the 'mask' for each component */
if (infoheader.biCompression == BI_BITFIELDS) {
unsigned long redMask, bluMask;
redMask = fgetl(f);
fgetl(f);
bluMask = fgetl(f);
if ((bluMask == 0x001f) && (redMask == 0x7C00))
bpp = 15;
else if ((bluMask == 0x001f) && (redMask == 0xF800))
bpp = 16;
else if ((bluMask == 0x0000FF) && (redMask == 0xFF0000))
bpp = 32;
else {
/* Unrecognised bit masks/depth */
fclose(f);
return FALSE;
}
rmask = fgetl(f);
gmask = fgetl(f);
bmask = fgetl(f);
}
else
rmask = gmask = bmask = 0;
image = fop_sequence_image(fop, type,
infoheader.biWidth,
infoheader.biHeight);
ABS((int)infoheader.biHeight));
if (!image) {
fclose(f);
return FALSE;
@ -593,18 +649,24 @@ static bool load_BMP(FileOp *fop)
break;
case BI_RLE8:
read_RLE8_compressed_image(f, image, &infoheader);
read_rle8_compressed_image(f, image, &infoheader);
break;
case BI_RLE4:
read_RLE4_compressed_image(f, image, &infoheader);
read_rle4_compressed_image(f, image, &infoheader);
break;
case BI_BITFIELDS:
read_bitfields_image(f, image, bpp, &infoheader);
if (read_bitfields_image(f, image, &infoheader, rmask, gmask, bmask) < 0) {
image_free(image);
fop_error(fop, _("Unsupported bitfields in the BMP file.\n"));
fclose(f);
return FALSE;
}
break;
default:
fop_error(fop, _("Unsupported BMP compression.\n"));
fclose(f);
return FALSE;
}
@ -614,10 +676,23 @@ static bool load_BMP(FileOp *fop)
fclose(f);
return FALSE;
}
else {
fclose(f);
return TRUE;
/* setup the file-data */
if (fop_sequence_get_filedata(fop) == NULL) {
BmpData *bmpdata = bmpdata_new();
bmpdata->format = format;
bmpdata->compression = infoheader.biCompression;
bmpdata->bits_per_pixel = infoheader.biBitCount;
bmpdata->red_mask = rmask;
bmpdata->green_mask = gmask;
bmpdata->blue_mask = bmask;
fop_sequence_set_filedata(fop, (FileData *)bmpdata);
}
fclose(f);
return TRUE;
}
static bool save_BMP(FileOp *fop)

View File

@ -30,6 +30,7 @@
#include "core/app.h"
#include "core/core.h"
#include "file/file.h"
#include "file/filedata.h"
#include "modules/gui.h"
#include "modules/palettes.h"
#include "raster/raster.h"
@ -536,11 +537,16 @@ void fop_operate(FileOp *fop)
}
fop->filename = jstrdup(jlist_first_data(fop->seq.filename_list));
/* set the frames range */
if (fop->sprite)
/* final setup */
if (fop->sprite != NULL) {
/* set the frames range */
sprite_set_frames(fop->sprite, frame);
/* set the frames range */
sprite_set_filedata(fop->sprite, fop->seq.filedata);
}
}
/* direct load from a file */
/* direct load from one file */
else {
/* call the "load" procedure */
if (!(*fop->format->load)(fop))
@ -679,6 +685,17 @@ void fop_free(FileOp *fop)
jfree(fop);
}
void fop_sequence_set_filedata(FileOp *fop, FileData *filedata)
{
assert(fop->seq.filedata == NULL);
fop->seq.filedata = filedata;
}
FileData *fop_sequence_get_filedata(FileOp *fop)
{
return fop->seq.filedata;
}
void fop_sequence_set_color(FileOp *fop, int index, int r, int g, int b)
{
palette_set_entry(fop->seq.palette, index, _rgba(r, g, b, 255));
@ -711,11 +728,12 @@ Image *fop_sequence_image(FileOp *fop, int imgtype, int w, int h)
return NULL;
}
layer_set_name(layer, _("Background"));
/* add the layer */
layer_add_layer(sprite->set, layer);
/* configure the layer as the background */
layer_configure_as_background(layer);
/* done */
fop->sprite = sprite;
fop->seq.layer = layer;
@ -867,6 +885,7 @@ static void fop_prepare_for_sequence(FileOp *fop)
{
fop->seq.filename_list = jlist_new();
fop->seq.palette = palette_new(0, MAX_PALETTE_COLORS);
fop->seq.filedata = NULL;
}
static FileFormat *get_fileformat(const char *extension)

View File

@ -40,6 +40,7 @@
#define FILE_LOAD_ONE_FRAME (1<<3)
struct Cel;
struct FileData;
struct Image;
struct Layer;
struct Palette;
@ -68,7 +69,7 @@ typedef struct FileOp
{
FileOpType type; /* operation type: 0=load, 1=save */
FileFormat *format;
struct Sprite *sprite; /* loaded sprite/sprite to be saved */
struct Sprite *sprite; /* loaded sprite, or sprite to be saved */
char *filename; /* file-name to load/save */
/* shared fields between threads */
@ -93,6 +94,7 @@ typedef struct FileOp
int frame;
struct Layer *layer;
struct Cel *last_cel;
struct FileData *filedata;
} seq;
} FileOp;
@ -115,6 +117,9 @@ void fop_done(FileOp *fop);
void fop_stop(FileOp *fop);
void fop_free(FileOp *fop);
void fop_sequence_set_filedata(FileOp *fop, struct FileData *filedata);
struct FileData *fop_sequence_get_filedata(FileOp *fop);
void fop_sequence_set_color(FileOp *fop, int index, int r, int g, int b);
void fop_sequence_get_color(FileOp *fop, int index, int *r, int *g, int *b);
struct Image *fop_sequence_image(FileOp *fi, int imgtype, int w, int h);

View File

@ -1,27 +1,58 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2008 David A. Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef UTIL_CROP_H
#define UTIL_CROP_H
void crop_sprite(void);
void crop_layer(void);
void crop_cel(void);
#endif /* UTIL_CROP_H */
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2008 David A. Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <assert.h>
#include "jinete/jbase.h"
#include "file/filedata.h"
FileData *filedata_new(int type, int size)
{
FileData *filedata;
assert(size >= sizeof(FileData));
filedata = jmalloc0(size);
if (filedata == NULL)
return NULL;
filedata->type = type;
filedata->size = size;
return filedata;
}
void filedata_free(FileData *filedata)
{
assert(filedata != NULL);
jfree(filedata);
}
BmpData *bmpdata_new(void)
{
BmpData *bmpdata = (BmpData *)filedata_new(FILEDATA_BMP,
sizeof(BmpData));
if (bmpdata == NULL)
return NULL;
return bmpdata;
}

63
src/file/filedata.h Normal file
View File

@ -0,0 +1,63 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2008 David A. Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef FILEDATA_H
#define FILEDATA_H
enum {
FILEDATA_BMP,
FILEDATA_MAX
};
/* data that can be in a file and could be useful to save the file
later in the same format */
typedef struct FileData
{
int type;
int size;
} FileData;
FileData *filedata_new(int type, int size);
void filedata_free(FileData *filedata);
/*********************************************************************
Data for BMP files
*********************************************************************/
#define BMPDATA_FORMAT_WINDOWS 12
#define BMPDATA_FORMAT_OS2 40
#define BMPDATA_COMPRESSION_RGB 0
#define BMPDATA_COMPRESSION_RLE8 1
#define BMPDATA_COMPRESSION_RLE4 2
#define BMPDATA_COMPRESSION_BITFIELDS 3
typedef struct BmpData
{
FileData head;
int format; /* BMP format */
int compression; /* BMP compression */
int bits_per_pixel; /* bits per pixel */
ase_uint32 red_mask; /* mask for red channel */
ase_uint32 green_mask; /* mask for green channel */
ase_uint32 blue_mask; /* mask for blue channel */
} BmpData;
BmpData *bmpdata_new(void);
#endif /* FILEDATA_H */

View File

@ -141,7 +141,7 @@ int jalert(const char *format, ...)
static JWidget create_alert(char *buf, JList *labels, JList *buttons)
{
JWidget box1, box2, box3, box4, box5, window = NULL;
JWidget box1, box2, grid, box3, box4, box5, window = NULL;
bool title = TRUE;
bool label = FALSE;
bool separator = FALSE;
@ -214,6 +214,7 @@ static JWidget create_alert(char *buf, JList *labels, JList *buttons)
if (window) {
box1 = jbox_new(JI_VERTICAL);
box2 = jbox_new(JI_VERTICAL);
grid = jgrid_new(1, FALSE);
box3 = jbox_new(JI_HORIZONTAL | JI_HOMOGENEOUS);
/* to identify by the user */
@ -236,7 +237,9 @@ static JWidget create_alert(char *buf, JList *labels, JList *buttons)
jwidget_add_child(box1, box4); /* filler */
jwidget_add_child(box1, box2); /* labels */
jwidget_add_child(box1, box5); /* filler */
jwidget_add_child(box1, box3); /* buttons */
jwidget_add_child(box1, grid); /* buttons */
jgrid_add_child(grid, box3, 1, 1, JI_CENTER | JI_BOTTOM);
JI_LIST_FOR_EACH(*labels, link)
jwidget_add_child(box2, (JWidget)link->data);

View File

@ -29,6 +29,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -51,6 +52,7 @@
#define TRANSLATE_ATTR(a) a
static JWidget convert_tag_to_widget(JXmlElem elem);
static int convert_align_value_to_flags(const char *value);
JWidget ji_load_widget(const char *filename, const char *name)
{
@ -92,6 +94,8 @@ static JWidget convert_tag_to_widget(JXmlElem elem)
JWidget widget = NULL;
JWidget child;
/* TODO error handling: add a message if the widget is bad specified */
/* box */
if (ustrcmp(elem_name, "box") == 0) {
bool horizontal = jxmlelem_has_attr(elem, "horizontal");
@ -106,37 +110,35 @@ static JWidget convert_tag_to_widget(JXmlElem elem)
else if (ustrcmp(elem_name, "button") == 0) {
const char *text = jxmlelem_get_attr(elem, "text");
if (text) {
widget = jbutton_new(TRANSLATE_ATTR(text));
if (widget) {
bool left = jxmlelem_has_attr(elem, "left");
bool right = jxmlelem_has_attr(elem, "right");
bool top = jxmlelem_has_attr(elem, "top");
bool bottom = jxmlelem_has_attr(elem, "bottom");
const char *_bevel = jxmlelem_get_attr(elem, "bevel");
widget = jbutton_new(text ? TRANSLATE_ATTR(text): NULL);
if (widget) {
bool left = jxmlelem_has_attr(elem, "left");
bool right = jxmlelem_has_attr(elem, "right");
bool top = jxmlelem_has_attr(elem, "top");
bool bottom = jxmlelem_has_attr(elem, "bottom");
const char *_bevel = jxmlelem_get_attr(elem, "bevel");
jwidget_set_align(widget,
(left ? JI_LEFT: (right ? JI_RIGHT: JI_CENTER)) |
(top ? JI_TOP: (bottom ? JI_BOTTOM: JI_MIDDLE)));
jwidget_set_align(widget,
(left ? JI_LEFT: (right ? JI_RIGHT: JI_CENTER)) |
(top ? JI_TOP: (bottom ? JI_BOTTOM: JI_MIDDLE)));
if (_bevel != NULL) {
char *bevel = jstrdup(_bevel);
int c, b[4];
char *tok;
if (_bevel != NULL) {
char *bevel = jstrdup(_bevel);
int c, b[4];
char *tok;
for (c=0; c<4; ++c)
b[c] = 0;
for (c=0; c<4; ++c)
b[c] = 0;
for (tok=ustrtok(bevel, " "), c=0;
tok;
tok=ustrtok(NULL, " "), ++c) {
if (c < 4)
b[c] = ustrtol(tok, NULL, 10);
}
jfree(bevel);
jbutton_set_bevel(widget, b[0], b[1], b[2], b[3]);
for (tok=ustrtok(bevel, " "), c=0;
tok;
tok=ustrtok(NULL, " "), ++c) {
if (c < 4)
b[c] = ustrtol(tok, NULL, 10);
}
jfree(bevel);
jbutton_set_bevel(widget, b[0], b[1], b[2], b[3]);
}
}
}
@ -144,20 +146,18 @@ static JWidget convert_tag_to_widget(JXmlElem elem)
else if (ustrcmp(elem_name, "check") == 0) {
const char *text = jxmlelem_get_attr(elem, "text");
if (text) {
widget = jcheck_new(TRANSLATE_ATTR(text));
if (widget) {
bool center = jxmlelem_has_attr(elem, "center");
bool right = jxmlelem_has_attr(elem, "right");
bool top = jxmlelem_has_attr(elem, "top");
bool bottom = jxmlelem_has_attr(elem, "bottom");
widget = jcheck_new(text ? TRANSLATE_ATTR(text): NULL);
if (widget) {
bool center = jxmlelem_has_attr(elem, "center");
bool right = jxmlelem_has_attr(elem, "right");
bool top = jxmlelem_has_attr(elem, "top");
bool bottom = jxmlelem_has_attr(elem, "bottom");
jwidget_set_align(widget,
(center ? JI_CENTER:
(right ? JI_RIGHT: JI_LEFT)) |
(top ? JI_TOP:
(bottom ? JI_BOTTOM: JI_MIDDLE)));
}
jwidget_set_align(widget,
(center ? JI_CENTER:
(right ? JI_RIGHT: JI_LEFT)) |
(top ? JI_TOP:
(bottom ? JI_BOTTOM: JI_MIDDLE)));
}
}
/* combobox */
@ -173,30 +173,38 @@ static JWidget convert_tag_to_widget(JXmlElem elem)
bool readonly = jxmlelem_has_attr(elem, "readonly");
widget = jentry_new(ustrtol(maxsize, NULL, 10),
text != NULL ? TRANSLATE_ATTR(text): "");
text ? TRANSLATE_ATTR(text): NULL);
if (readonly)
jentry_readonly(widget, TRUE);
}
}
/* grid */
else if (ustrcmp(elem_name, "grid") == 0) {
const char *columns = jxmlelem_get_attr(elem, "columns");
bool same_width_columns = jxmlelem_has_attr(elem, "same_width_columns");
if (columns != NULL) {
widget = jgrid_new(ustrtol(columns, NULL, 10),
same_width_columns);
}
}
/* label */
else if (ustrcmp(elem_name, "label") == 0) {
const char *text = jxmlelem_get_attr(elem, "text");
if (text) {
widget = jlabel_new(TRANSLATE_ATTR(text));
if (widget) {
bool center = jxmlelem_has_attr(elem, "center");
bool right = jxmlelem_has_attr(elem, "right");
bool top = jxmlelem_has_attr(elem, "top");
bool bottom = jxmlelem_has_attr(elem, "bottom");
widget = jlabel_new(text ? TRANSLATE_ATTR(text): NULL);
if (widget) {
bool center = jxmlelem_has_attr(elem, "center");
bool right = jxmlelem_has_attr(elem, "right");
bool top = jxmlelem_has_attr(elem, "top");
bool bottom = jxmlelem_has_attr(elem, "bottom");
jwidget_set_align(widget,
(center ? JI_CENTER:
(right ? JI_RIGHT: JI_LEFT)) |
(top ? JI_TOP:
(bottom ? JI_BOTTOM: JI_MIDDLE)));
}
jwidget_set_align(widget,
(center ? JI_CENTER:
(right ? JI_RIGHT: JI_LEFT)) |
(top ? JI_TOP:
(bottom ? JI_BOTTOM: JI_MIDDLE)));
}
}
/* listbox */
@ -207,8 +215,7 @@ static JWidget convert_tag_to_widget(JXmlElem elem)
else if (ustrcmp(elem_name, "listitem") == 0) {
const char *text = jxmlelem_get_attr(elem, "text");
if (text != NULL)
widget = jlistitem_new(TRANSLATE_ATTR(text));
widget = jlistitem_new(text ? TRANSLATE_ATTR(text): NULL);
}
/* panel */
else if (ustrcmp(elem_name, "panel") == 0) {
@ -223,21 +230,19 @@ static JWidget convert_tag_to_widget(JXmlElem elem)
const char *text = jxmlelem_get_attr(elem, "text");
const char *group = jxmlelem_get_attr(elem, "group");
if (text != NULL && group != NULL) {
widget = jradio_new(TRANSLATE_ATTR(text),
ustrtol(group, NULL, 10));
if (widget) {
bool center = jxmlelem_has_attr(elem, "center");
bool right = jxmlelem_has_attr(elem, "right");
bool top = jxmlelem_has_attr(elem, "top");
bool bottom = jxmlelem_has_attr(elem, "bottom");
widget = jradio_new(text ? TRANSLATE_ATTR(text): NULL,
group ? ustrtol(group, NULL, 10): 1);
if (widget) {
bool center = jxmlelem_has_attr(elem, "center");
bool right = jxmlelem_has_attr(elem, "right");
bool top = jxmlelem_has_attr(elem, "top");
bool bottom = jxmlelem_has_attr(elem, "bottom");
jwidget_set_align(widget,
(center ? JI_CENTER:
(right ? JI_RIGHT: JI_LEFT)) |
(top ? JI_TOP:
(bottom ? JI_BOTTOM: JI_MIDDLE)));
}
jwidget_set_align(widget,
(center ? JI_CENTER:
(right ? JI_RIGHT: JI_LEFT)) |
(top ? JI_TOP:
(bottom ? JI_BOTTOM: JI_MIDDLE)));
}
}
/* separator */
@ -274,6 +279,7 @@ static JWidget convert_tag_to_widget(JXmlElem elem)
/* TODO add translatable support */
/* TODO here we need jxmlelem_get_text(elem) */
/* widget = jtextbox_new(tag->text, wordwrap ? JI_WORDWRAP: 0); */
assert(FALSE);
}
/* view */
else if (ustrcmp(elem_name, "view") == 0) {
@ -337,12 +343,27 @@ static JWidget convert_tag_to_widget(JXmlElem elem)
/* children */
JI_LIST_FOR_EACH(elem->head.children, link) {
if (((JXmlNode)link->data)->type == JI_XML_ELEM) {
child = convert_tag_to_widget(link->data);
JXmlElem child_elem = (JXmlElem)link->data;
child = convert_tag_to_widget(child_elem);
if (child != NULL) {
/* attach the child in the view */
if (widget->type == JI_VIEW) {
jview_attach(widget, child);
break;
}
/* add the child in the grid */
else if (widget->type == JI_GRID) {
const char *cell_hspan = jxmlelem_get_attr(child_elem, "cell_hspan");
const char *cell_vspan = jxmlelem_get_attr(child_elem, "cell_vspan");
const char *cell_align = jxmlelem_get_attr(child_elem, "cell_align");
int hspan = cell_hspan ? ustrtol(cell_hspan, NULL, 10): 1;
int vspan = cell_vspan ? ustrtol(cell_vspan, NULL, 10): 1;
int align = cell_align ? convert_align_value_to_flags(cell_align): 0;
jgrid_add_child(widget, child, hspan, vspan, align);
}
/* just add the child in any other kind of widget */
else
jwidget_add_child(widget, child);
}
@ -358,3 +379,44 @@ static JWidget convert_tag_to_widget(JXmlElem elem)
return widget;
}
static int convert_align_value_to_flags(const char *value)
{
char *tok, *ptr = jstrdup(value);
int flags = 0;
for (tok=ustrtok(ptr, " ");
tok != NULL;
tok=ustrtok(NULL, " ")) {
if (ustrcmp(tok, "horizontal") == 0) {
flags |= JI_HORIZONTAL;
}
else if (ustrcmp(tok, "vertical") == 0) {
flags |= JI_VERTICAL;
}
else if (ustrcmp(tok, "left") == 0) {
flags |= JI_LEFT;
}
else if (ustrcmp(tok, "center") == 0) {
flags |= JI_CENTER;
}
else if (ustrcmp(tok, "right") == 0) {
flags |= JI_RIGHT;
}
else if (ustrcmp(tok, "top") == 0) {
flags |= JI_TOP;
}
else if (ustrcmp(tok, "middle") == 0) {
flags |= JI_MIDDLE;
}
else if (ustrcmp(tok, "bottom") == 0) {
flags |= JI_BOTTOM;
}
else if (ustrcmp(tok, "homogeneous") == 0) {
flags |= JI_HOMOGENEOUS;
}
}
jfree(ptr);
return flags;
}

View File

@ -288,10 +288,6 @@ bool jmanager_generate_messages(JWidget manager)
JLink link;
int c;
/* make some OSes happy */
yield_timeslice();
rest(1);
/* poll keyboard */
poll_keyboard();
@ -560,7 +556,14 @@ bool jmanager_generate_messages(JWidget manager)
/* generate redraw events */
jwidget_flush_redraw(manager);
return !jlist_empty(msg_queue);
if (!jlist_empty(msg_queue))
return TRUE;
else {
/* make some OSes happy */
yield_timeslice();
rest(1);
return FALSE;
}
}
void jmanager_dispatch_messages(JWidget manager)

View File

@ -74,6 +74,7 @@ enum {
JI_CURSOR_NORMAL_ADD,
JI_CURSOR_FORBIDDEN,
JI_CURSOR_HAND,
JI_CURSOR_SCROLL,
JI_CURSOR_MOVE,
JI_CURSOR_SIZE_TL,
JI_CURSOR_SIZE_T,

View File

@ -136,7 +136,7 @@ static bool textbox_msg_proc(JWidget widget, JMessage msg)
JWidget view = jwidget_get_view(widget);
if (view) {
jwidget_hard_capture_mouse(widget);
jmouse_set_cursor(JI_CURSOR_MOVE);
jmouse_set_cursor(JI_CURSOR_SCROLL);
return TRUE;
}
break;

View File

@ -151,14 +151,24 @@ static bool tip_hook(JWidget widget, JMessage msg)
if (msg->timer.timer_id == tip->timer_id) {
if (!tip->window) {
JWidget window = tipwindow_new(tip->text, TRUE);
int x = tip->widget->rc->x1;
int y = tip->widget->rc->y2;
int w = jrect_w(window->rc);
int h = jrect_h(window->rc);
/* int x = tip->widget->rc->x1; */
/* int y = tip->widget->rc->y2; */
int x = jmouse_x(0)+12;
int y = jmouse_y(0)+12;
int w, h;
tip->window = window;
jwindow_remap(window);
w = jrect_w(window->rc);
h = jrect_h(window->rc);
if (x+w > JI_SCREEN_W) {
x = jmouse_x(0) - w - 4;
y = jmouse_y(0);
}
jwindow_position(window,
MID(0, x, JI_SCREEN_W-w),
MID(0, y, JI_SCREEN_H-h));

View File

@ -367,6 +367,28 @@ JXmlElem jxmlelem_get_elem_by_id(JXmlElem elem, const char *id)
return NULL;
}
JXmlElem jxmlelem_get_elem_by_name(JXmlElem elem, const char *name)
{
const char *elem_name = jxmlelem_get_name(elem);
JLink link;
/* this is the element with the specified ID */
if (elem_name && strcmp(elem_name, name) == 0)
return elem;
/* go through the children */
JI_LIST_FOR_EACH(((JXmlNode)elem)->children, link) {
JXmlNode child = (JXmlNode)link->data;
if (child->type == JI_XML_ELEM) {
JXmlElem found = jxmlelem_get_elem_by_name((JXmlElem)child, name);
if (found)
return found;
}
}
return NULL;
}
/**********************************************************************/
/* JXmlText */
/**********************************************************************/

View File

@ -113,6 +113,7 @@ const char *jxmlelem_get_attr(JXmlElem elem, const char *name);
void jxmlelem_set_attr(JXmlElem elem, const char *name, const char *value);
JXmlElem jxmlelem_get_elem_by_id(JXmlElem elem, const char *id);
JXmlElem jxmlelem_get_elem_by_name(JXmlElem elem, const char *name);
/* JXmlText ******************************************/

View File

@ -53,8 +53,8 @@
/* "icons_data" indexes */
enum {
FIRST_CURSOR = 0,
LAST_CURSOR = 13,
ICON_CHECK_EDGE = 14,
LAST_CURSOR = 14,
ICON_CHECK_EDGE = 15,
ICON_CHECK_MARK,
ICON_CLOSE,
ICON_MENU_MARK,
@ -72,6 +72,7 @@ static struct {
{ FALSE, default_theme_cnoradd },
{ FALSE, default_theme_cforbidden },
{ FALSE, default_theme_chand },
{ FALSE, default_theme_cscroll },
{ FALSE, default_theme_cmove },
{ FALSE, default_theme_csizetl },
{ FALSE, default_theme_csizet },
@ -251,6 +252,7 @@ static BITMAP *theme_set_cursor(int type, int *focus_x, int *focus_y)
case JI_CURSOR_NORMAL:
case JI_CURSOR_NORMAL_ADD:
case JI_CURSOR_FORBIDDEN:
case JI_CURSOR_MOVE:
*focus_x = 0;
*focus_y = 0;
break;
@ -258,7 +260,7 @@ static BITMAP *theme_set_cursor(int type, int *focus_x, int *focus_y)
*focus_x = 5;
*focus_y = 3;
break;
case JI_CURSOR_MOVE:
case JI_CURSOR_SCROLL:
*focus_x = 8;
*focus_y = 8;
break;

View File

@ -62,22 +62,22 @@ static unsigned char default_theme_chand[258] = {
static unsigned char default_theme_cmove[258] = {
16, 16,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 3, 1, 3, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 3, 1, 3, 1, 3, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 3, 1, 3, 1, 3, 1, 3, 1, 0, 0, 0,
0, 0, 0, 0, 1, 3, 1, 3, 1, 3, 1, 3, 1, 0, 0, 0,
0, 0, 0, 1, 1, 3, 1, 3, 1, 3, 1, 3, 1, 0, 0, 0,
0, 0, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 0, 0, 0,
0, 0, 1, 3, 1, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0,
0, 0, 1, 3, 1, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0,
0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0,
0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0,
0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0,
0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3, 1, 1, 1, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
3, 1, 1, 1, 1, 3, 0, 0, 3, 1, 3, 0, 0, 0, 0, 0,
3, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 3, 0, 0, 0, 0,
3, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 0, 0, 0,
3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 3, 0, 0,
3, 1, 1, 1, 3, 3, 3, 3, 3, 1, 3, 3, 1, 1, 3, 0,
3, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
3, 1, 3, 0, 3, 1, 1, 3, 3, 1, 3, 3, 1, 1, 3, 0,
3, 3, 0, 0, 0, 3, 1, 3, 3, 1, 3, 3, 1, 3, 0, 0,
0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 3, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 3, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 3, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0
};
static unsigned char default_theme_cnoradd[258] = {
@ -120,6 +120,26 @@ static unsigned char default_theme_cnormal[258] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static unsigned char default_theme_cscroll[258] = {
16, 16,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 3, 1, 3, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 3, 1, 3, 1, 3, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 3, 1, 3, 1, 3, 1, 3, 1, 0, 0, 0,
0, 0, 0, 0, 1, 3, 1, 3, 1, 3, 1, 3, 1, 0, 0, 0,
0, 0, 0, 1, 1, 3, 1, 3, 1, 3, 1, 3, 1, 0, 0, 0,
0, 0, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 0, 0, 0,
0, 0, 1, 3, 1, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0,
0, 0, 1, 3, 1, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0,
0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0,
0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0,
0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0,
0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static unsigned char default_theme_csizeb[258] = {
16, 16,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

Binary file not shown.

Binary file not shown.

View File

@ -574,19 +574,13 @@ void draw_color(BITMAP *bmp, int x1, int y1, int x2, int y2,
if (!graph)
return;
rectgrid(graph, 0, 0, w-1, h-1, grid, grid);
drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0);
set_trans_blender(0, 0, 0, color_get_alpha(imgtype, color));
{
int rgb_bitmap_color = get_color_for_image(imgtype, color);
color_t color2 = color_rgb(_rgba_getr(rgb_bitmap_color),
_rgba_getg(rgb_bitmap_color),
_rgba_getb(rgb_bitmap_color),
_rgba_geta(rgb_bitmap_color));
_rgba_getb(rgb_bitmap_color));
rectfill(graph, 0, 0, w-1, h-1, get_color_for_allegro(32, color2));
}
drawing_mode(DRAW_MODE_SOLID, NULL, 0, 0);
use_current_sprite_rgb_map();
blit(graph, bmp, 0, 0, x1, y1, w, h);
@ -600,17 +594,11 @@ void draw_color(BITMAP *bmp, int x1, int y1, int x2, int y2,
if (!graph)
return;
rectgrid(graph, 0, 0, w-1, h-1, grid, grid);
drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0);
set_trans_blender(0, 0, 0, color_get_alpha(imgtype, color));
{
int gray_bitmap_color = get_color_for_image(imgtype, color);
color_t color2 = color_gray(_graya_getv(gray_bitmap_color),
_graya_geta(gray_bitmap_color));
color_t color2 = color_gray(_graya_getv(gray_bitmap_color));
rectfill(graph, 0, 0, w-1, h-1, get_color_for_allegro(32, color2));
}
drawing_mode(DRAW_MODE_SOLID, NULL, 0, 0);
use_current_sprite_rgb_map();
blit(graph, bmp, 0, 0, x1, y1, w, h);

View File

@ -46,14 +46,15 @@ enum {
GFX_ANI_LAST,
GFX_TOOL_MARKER,
GFX_TOOL_DOTS,
GFX_TOOL_PENCIL,
GFX_TOOL_BRUSH,
GFX_TOOL_ERASER,
GFX_TOOL_FLOODFILL,
GFX_TOOL_SPRAY,
GFX_TOOL_LINE,
GFX_TOOL_RECTANGLE,
GFX_TOOL_ELLIPSE,
GFX_TOOL_BLUR,
GFX_TOOL_CONFIGURATION,
GFX_TARGET_ONE,
@ -70,10 +71,6 @@ enum {
GFX_BRUSH_SQUARE,
GFX_BRUSH_LINE,
GFX_DRAWMODE_OPAQUE,
GFX_DRAWMODE_GLASS,
GFX_DRAWMODE_SEMI,
GFX_SCALE_1,
GFX_SCALE_2,
GFX_SCALE_3,

View File

@ -94,16 +94,6 @@ static DATA gfx_data[GFX_BITMAP_COUNT] =
" "
"# #"
"## ## ##" },
/* GFX_TOOL_DOTS */
{ 8, 8,
" # "
" # # "
" "
" # "
" "
" # "
" "
" # " },
/* GFX_TOOL_PENCIL */
{ 8, 8,
" "
@ -124,6 +114,16 @@ static DATA gfx_data[GFX_BITMAP_COUNT] =
" #"
" ###"
" #### " },
/* GFX_TOOL_ERASER */
{ 8, 8,
" "
" #### "
" # ##"
" # # #"
"##### #"
"# # # "
"# ## "
" #### " },
/* GFX_TOOL_FLOODFILL */
{ 8, 8,
" "
@ -174,6 +174,16 @@ static DATA gfx_data[GFX_BITMAP_COUNT] =
" # # "
" #### "
" " },
/* GFX_TOOL_BLUR */
{ 8, 8,
" # "
" # "
" # # "
" # # "
"# # # "
"# # "
" # # "
" ### " },
/* GFX_TOOL_CONFIGURATION */
{ 8, 8,
" # # "
@ -326,32 +336,6 @@ static DATA gfx_data[GFX_BITMAP_COUNT] =
" # "
" # "
" #" },
/* GFX_DRAWMODE_OPAQUE */
{ 7, 7,
"## "
"### "
" ### "
" ### "
" ### "
" ###"
" ##" },
/* GFX_DRAWMODE_GLASS */
{ 7, 7,
"## "
"### .."
" ##%..."
" %%%. "
" ..%%# "
"....###"
".. ##" },
/* GFX_DRAWMODE_SEMI */
{ 8, 6,
" # # "
"# # # "
" # # # "
" # # # "
" # # #"
" # # " },
/* GFX_SCALE_1 */
{ 11, 11,
"## "

View File

@ -44,6 +44,7 @@
#include "modules/palettes.h"
#include "modules/rootmenu.h"
#include "modules/sprites.h"
#include "modules/tools.h"
#include "raster/sprite.h"
#include "script/script.h"
#include "util/recscr.h"
@ -800,9 +801,15 @@ static bool manager_msg_proc(JWidget widget, JMessage msg)
break;
case JM_KEYPRESSED: {
/* check for commands */
Command *command = command_get_by_key(msg);
if (!command)
if (!command) {
/* check for tools */
Tool *tool = get_tool_by_key(msg);
if (tool != NULL)
select_tool(tool);
break;
}
/* the screen shot is available in everywhere */
if (strcmp(command->name, CMD_SCREEN_SHOT) == 0) {

View File

@ -30,6 +30,7 @@
#include "core/dirs.h"
#include "intl/intl.h"
#include "modules/rootmenu.h"
#include "modules/tools.h"
#include "util/filetoks.h"
#include "widgets/menuitem.h"
@ -89,9 +90,10 @@ JWidget get_cel_popup_menu(void) { return cel_popup_menu; }
static int load_root_menu(void)
{
JLink link, link2;
DIRS *dirs, *dir;
JLink link;
JXml xml;
JXmlElem child;
if (app_get_menubar())
jmenubar_set_menu(app_get_menubar(), NULL);
@ -125,7 +127,9 @@ static int load_root_menu(void)
xml = jxml_new_from_file(dir->path);
if (xml && jxml_get_root(xml)) {
/**************************************************/
/* load menus */
/* load menus */
/**************************************************/
PRINTF("Trying to menus from \"%s\"...\n", dir->path);
root_menu = load_menu_by_id(xml, "main_menu", dir->path);
@ -140,20 +144,20 @@ static int load_root_menu(void)
filters_popup_menu = load_menu_by_id(xml, "filters_popup", dir->path);
/**************************************************/
/* load keyboard shortcuts */
PRINTF("Trying to load keyboard shortcuts from \"%s\"...\n", dir->path);
/* load keyboard shortcuts for commands */
/**************************************************/
PRINTF("Loading commands shortcuts from \"%s\"...\n", dir->path);
/* find the <keyboard> element */
JI_LIST_FOR_EACH(((JXmlNode)jxml_get_root(xml))->children, link) {
JXmlNode child = (JXmlNode)link->data;
/* is it <keyboard>? */
if (child->type == JI_XML_ELEM &&
strcmp(jxmlelem_get_name((JXmlElem)child), "keyboard") == 0) {
/* for each children in <keyboard>...</keyboard> */
JI_LIST_FOR_EACH(child->children, link2) {
JXmlNode child2 = (JXmlNode)link2->data;
child = jxmlelem_get_elem_by_name(jxml_get_root(xml), "keyboard");
if (child != NULL) {
/* find the <menus> element */
child = jxmlelem_get_elem_by_name(child, "commands");
if (child != NULL) {
/* for each children in <keyboard><commands>...</commands></keyboard> */
JI_LIST_FOR_EACH(child->head.children, link) {
JXmlNode child2 = (JXmlNode)link->data;
/* it is a <key> element? */
if (child2->type == JI_XML_ELEM &&
@ -167,6 +171,7 @@ static int load_root_menu(void)
bool first_shortcut = !command->accel;
/* add the keyboard shortcut to the command */
PRINTF("- Shortcut for command `%s': <%s>\n", command_name, command_key);
command_add_key(command, command_key);
/* add the shortcut to the menuitems with this
@ -179,10 +184,44 @@ static int load_root_menu(void)
}
}
}
break;
}
}
/**************************************************/
/* load keyboard shortcuts for tools */
/**************************************************/
PRINTF("Loading tools shortcuts from \"%s\"...\n", dir->path);
/* find the <keyboard> element */
child = jxmlelem_get_elem_by_name(jxml_get_root(xml), "keyboard");
if (child != NULL) {
/* find the <tools> element */
child = jxmlelem_get_elem_by_name(child, "tools");
if (child != NULL) {
/* for each children in <keyboard><tools>...</tools></keyboard> */
JI_LIST_FOR_EACH(child->head.children, link) {
JXmlNode child2 = (JXmlNode)link->data;
/* it is a <key> element? */
if (child2->type == JI_XML_ELEM &&
strcmp(jxmlelem_get_name((JXmlElem)child2), "key") == 0) {
/* finally, we can read the <key /> */
const char *tool_name = jxmlelem_get_attr((JXmlElem)child2, "tool");
const char *tool_key = jxmlelem_get_attr((JXmlElem)child2, "shortcut");
if (tool_name && tool_key) {
Tool *tool = get_tool_by_name(tool_name);
if (tool) {
/* add the keyboard shortcut to the tool */
PRINTF("- Shortcut for tool `%s': <%s>\n", tool_name, tool_key);
tool_add_key(tool, tool_key);
}
}
}
}
}
}
/* free the XML file */
jxml_free(xml);
}

View File

@ -46,8 +46,8 @@ Sprite *current_sprite = NULL;
static JList sprites_list;
static Sprite *clipboard_sprite;
static Stock *layer_get_images(Sprite *sprite, Layer *layer, int target, int write);
static void layer_get_pos(Sprite *sprite, Layer *layer, int target, int write, int **x, int **y, int *count);
static Stock *layer_get_images(Sprite *sprite, Layer *layer, int target, bool write);
static void layer_get_pos(Sprite *sprite, Layer *layer, int target, bool write, int **x, int **y, int *count);
int init_module_sprites(void)
{
@ -239,15 +239,15 @@ Stock *sprite_get_images(Sprite *sprite, int target, int write, int **x, int **y
return stock;
}
static Stock *layer_get_images(Sprite *sprite, Layer *layer, int target, int write)
static Stock *layer_get_images(Sprite *sprite, Layer *layer, int target, bool write)
{
Stock *stock = stock_new_ref(sprite->imgtype);
int frame = sprite->frame;
if (!layer->readable)
if (!layer_is_readable(layer))
return stock;
if (write && !layer->writable)
if (write && !layer_is_writable(layer))
return stock;
switch (layer->gfxobj.type) {
@ -294,14 +294,14 @@ static Stock *layer_get_images(Sprite *sprite, Layer *layer, int target, int wri
return stock;
}
static void layer_get_pos(Sprite *sprite, Layer *layer, int target, int write, int **x, int **y, int *count)
static void layer_get_pos(Sprite *sprite, Layer *layer, int target, bool write, int **x, int **y, int *count)
{
int frame = sprite->frame;
if (!layer->readable)
if (!layer_is_readable(layer))
return;
if (write && !layer->writable)
if (write && !layer_is_writable(layer))
return;
switch (layer->gfxobj.type) {

File diff suppressed because it is too large Load Diff

View File

@ -23,61 +23,79 @@
#include "jinete/jrect.h"
#include "core/color.h"
#include "raster/algo.h"
struct _GList;
struct Brush;
struct Dirty;
struct Image;
struct Layer;
struct Mask;
struct Sprite;
#define TOOL_ACCUMULATE_DIRTY (1<<1)
#define TOOL_FIRST2LAST (1<<2)
#define TOOL_OLD2LAST (1<<3)
#define TOOL_FOURCHAIN (1<<4)
#define TOOL_ACCEPT_FILL (1<<5)
#define TOOL_UPDATE_ALL (1<<6)
#define TOOL_UPDATE_POINT (1<<7)
#define TOOL_UPDATE_TRACE (1<<8)
#define TOOL_UPDATE_BOX (1<<9)
#define TOOL_UPDATE_SPRAY (1<<10)
#define TOOL_UPDATE_LAST4 (1<<11)
#define TOOL_EIGHT_ANGLES (1<<12)
enum {
TOOL_MARKER,
TOOL_PENCIL,
TOOL_BRUSH,
TOOL_ERASER,
TOOL_FLOODFILL,
TOOL_SPRAY,
TOOL_LINE,
TOOL_RECTANGLE,
TOOL_ELLIPSE,
TOOL_BLUR,
MAX_TOOLS
};
enum {
DRAWMODE_OPAQUE,
DRAWMODE_GLASS,
DRAWMODE_SEMI,
INK_OPAQUE,
INK_GLASS,
INK_SOFTEN,
INK_REPLACE,
MAX_INKS
};
typedef struct Tool Tool;
typedef struct ToolData ToolData;
struct Tool
{
const char *key;
const char *name;
const char *translated_name;
const char *tips;
int flags;
void (*put)(struct Dirty *dirty, int x1, int y1, int x2, int y2);
void (*preprocess_data)(ToolData *data);
void (*draw_trace)(int x1, int y1, int x2, int y2, ToolData *data);
JAccel accel;
};
struct ToolData
{
struct Layer *layer;
struct Image *src_image; /* where we can get pixels (readonly image) */
struct Image *dst_image; /* where we should put pixels */
struct Brush *brush; /* brush to be used with the ink */
struct Mask *mask; /* mask to limit the paint */
int mask_x, mask_y; /* mask offset */
int color; /* primary color to draw */
int other_color; /* secondary color to draw */
bool left_button; /* did the user start the trace with the left mouse button? */
AlgoHLine ink_hline_proc;
int opacity;
bool tiled;
};
extern Tool *current_tool;
extern Tool ase_tool_marker;
extern Tool ase_tool_dots;
extern Tool ase_tool_pencil;
extern Tool ase_tool_brush;
extern Tool ase_tool_floodfill;
extern Tool ase_tool_spray;
extern Tool ase_tool_line;
extern Tool ase_tool_rectangle;
extern Tool ase_tool_ellipse;
extern Tool *ase_tools_list[];
extern Tool *tools_list[];
int init_module_tools(void);
void exit_module_tools(void);
void refresh_tools_names(void);
void tool_add_key(Tool *tool, const char *string);
bool tool_is_key_pressed(Tool *tool, JMessage msg);
Tool *get_tool_by_name(const char *name);
Tool *get_tool_by_key(JMessage msg);
void select_tool(Tool *tool);
void select_tool_by_name(const char *tool_name);
struct Brush *get_brush(void);
int get_brush_type(void);
@ -115,10 +133,13 @@ void set_cursor_color(color_t color);
int get_thickness_for_cursor(void);
void control_tool(JWidget editor, Tool *tool, color_t color);
void control_tool(JWidget editor, Tool *tool,
color_t color,
color_t other_color,
bool left_button);
void do_tool_points(struct Sprite *sprite, Tool *tool, color_t color,
int npoints, int *x, int *y);
/* void do_tool_points(struct Sprite *sprite, Tool *tool, color_t color, */
/* int npoints, int *x, int *y); */
void apply_grid(int *x, int *y, bool flexible);

View File

@ -18,6 +18,7 @@
#include "config.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
@ -73,43 +74,6 @@ void SetBrush(const char *string)
jfree(copy);
}
/* string = "draw_mode glass_dirty"
draw_mode: opaque, glass, semi (default=opaque)
glass_dirty: 0-255 (default=128)
*/
void SetDrawMode(const char *string)
{
char *copy = jstrdup(string);
char *tok;
int count;
int draw_mode = DRAWMODE_OPAQUE;
int glass_dirty = 128;
for (tok=strtok(copy, " "), count=0; tok;
tok=strtok(NULL, " "), count++) {
switch (count) {
case 0:
if (strcmp(tok, "opaque") == 0)
draw_mode = DRAWMODE_OPAQUE;
else if (strcmp(tok, "glass") == 0)
draw_mode = DRAWMODE_GLASS;
else if (strcmp(tok, "semi") == 0)
draw_mode = DRAWMODE_SEMI;
break;
case 1:
glass_dirty = strtol(tok, NULL, 0);
break;
}
}
set_brush_mode(draw_mode);
set_glass_dirty(MID(0, glass_dirty, 255));
jfree(copy);
}
/* string = "tool_name x,y x,y x,y ..."
tool_name: marker, dots, pencil, brush, floodfill, spray, line,
rectangle, ellipse
@ -155,7 +119,9 @@ void ToolTrace(const char *string, const char *_color)
}
if (npoints > 0) {
do_tool_points(sprite, current_tool, color, npoints, x, y);
/* TODO */
assert(FALSE);
/* do_tool_points(sprite, current_tool, color, npoints, x, y); */
jfree(x);
jfree(y);
}
@ -180,7 +146,6 @@ static int cfg_target_images;
static int cfg_tools_brush_type;
static int cfg_tools_brush_size;
static int cfg_tools_brush_angle;
static int cfg_tools_brush_mode;
static int cfg_tools_glass_dirty;
static int cfg_tools_spray_width;
static int cfg_tools_air_speed;
@ -224,7 +189,6 @@ void ResetConfig(void)
cfg_tools_brush_type = get_brush_type();
cfg_tools_brush_size = get_brush_size();
cfg_tools_brush_angle = get_brush_angle();
cfg_tools_brush_mode = get_brush_mode();
cfg_tools_glass_dirty = get_glass_dirty();
cfg_tools_spray_width = get_spray_width();
cfg_tools_air_speed = get_air_speed();
@ -242,7 +206,6 @@ void ResetConfig(void)
set_brush_type(BRUSH_CIRCLE);
set_brush_size(1);
set_brush_angle(0);
set_brush_mode(DRAWMODE_OPAQUE);
set_cursor_color(color_mask());
set_glass_dirty(128);
set_spray_width(16);
@ -284,7 +247,6 @@ void RestoreConfig(void)
set_brush_type(cfg_tools_brush_type);
set_brush_size(cfg_tools_brush_size);
set_brush_angle(cfg_tools_brush_angle);
set_brush_mode(cfg_tools_brush_mode);
set_glass_dirty(cfg_tools_glass_dirty);
set_spray_width(cfg_tools_spray_width);
set_air_speed(cfg_tools_air_speed);

View File

@ -20,7 +20,6 @@
#define MODULES_TOOLS2_H
void SetBrush(const char *string);
void SetDrawMode(const char *string);
void ToolTrace(const char *string, const char *color);
void ResetConfig(void);

View File

@ -104,48 +104,47 @@ static void clean_brush (Brush *brush)
}
/* Regenerates the brush bitmap and its rectangle's region. */
static void regenerate_brush (Brush *brush)
static void regenerate_brush(Brush *brush)
{
int x, y;
clean_brush (brush);
clean_brush(brush);
brush->image = image_new (IMAGE_BITMAP, brush->size, brush->size);
image_clear (brush->image, 0);
brush->image = image_new(IMAGE_BITMAP, brush->size, brush->size);
image_clear(brush->image, 0);
switch (brush->type) {
case BRUSH_CIRCLE:
image_ellipsefill (brush->image, 0, 0, brush->size-1, brush->size-1, 1);
image_ellipsefill(brush->image, 0, 0, brush->size-1, brush->size-1, 1);
break;
case BRUSH_SQUARE:
image_rectfill (brush->image, 0, 0, brush->size-1, brush->size-1, 1);
image_rectfill(brush->image, 0, 0, brush->size-1, brush->size-1, 1);
break;
case BRUSH_LINE: {
double a = PI * brush->angle / 180;
x = cos (a) * brush->size/2;
y = -sin (a) * brush->size/2;
image_line (brush->image,
brush->size/2-x,
brush->size/2-y,
brush->size/2+x,
brush->size/2+y, 1);
int r = brush->size/2;
x = cos(a) * r;
y = -sin(a) * r;
image_line(brush->image, r-x, r-y, r+x, r+y, 1);
image_line(brush->image, r-x-1, r-y, r+x-1, r+y, 1);
break;
}
}
brush->scanline = jnew (struct BrushScanline, brush->size);
brush->scanline = jnew(struct BrushScanline, brush->size);
for (y=0; y<brush->size; y++) {
brush->scanline[y].state = FALSE;
for (x=0; x<brush->size; x++) {
if (image_getpixel (brush->image, x, y)) {
if (image_getpixel(brush->image, x, y)) {
brush->scanline[y].x1 = x;
for (; x<brush->size; x++)
if (!image_getpixel (brush->image, x, y))
if (!image_getpixel(brush->image, x, y))
break;
brush->scanline[y].x2 = x-1;

View File

@ -181,6 +181,35 @@ Dirty *dirty_new_copy(Dirty *src)
return dst;
}
Dirty *dirty_new_from_differences(Image *image, Image *image_diff)
{
Dirty *dirty = dirty_new(image, 0, 0, image->w, image->h, FALSE);
int x, y, x1, x2;
for (y=0; y<image->h; y++) {
x1 = x2 = -1;
for (x=0; x<image->w; x++) {
if (image_getpixel(image, x, y) != image_getpixel(image_diff, x, y)) {
x1 = x;
break;
}
}
for (x=image->w-1; x>=0; x--) {
if (image_getpixel(image, x, y) != image_getpixel(image_diff, x, y)) {
x2 = x;
break;
}
}
if (x1 >= 0 && x2 >= 0)
dirty_hline(dirty, x1, y, x2);
}
return dirty;
}
void dirty_free(Dirty *dirty)
{
register struct DirtyRow *row;
@ -610,7 +639,7 @@ void dirty_line_brush(Dirty *dirty, Brush *brush, int x1, int y1, int x2, int y2
(AlgoPixel)algo_putbrush);
}
void dirty_get(Dirty *dirty)
void dirty_save_image_data(Dirty *dirty)
{
register int v, u, shift = IMAGE_SHIFT(dirty->image);
@ -627,7 +656,7 @@ void dirty_get(Dirty *dirty)
}
}
void dirty_put(Dirty *dirty)
void dirty_restore_image_data(Dirty *dirty)
{
register struct DirtyRow *row;
register struct DirtyCol *col;

View File

@ -26,16 +26,6 @@ struct Mask;
#define DIRTY_VALID_COLUMN 1
#define DIRTY_MUSTBE_UPDATED 2
#define IMAGE_ADDRESS(image,x,y) \
((void *)(image)->line[(y)] + IMAGE_LINE_SIZE((image), (x))) \
#define IMAGE_SHIFT(d) \
(((d)->imgtype == IMAGE_RGB)? 2: \
((d)->imgtype == IMAGE_GRAYSCALE)? 1: 0)
#define IMAGE_LINE_SIZE(image, width) \
((width) << IMAGE_SHIFT(image))
#define DIRTY_LINE_SIZE(width) \
(IMAGE_LINE_SIZE(dirty->image, width))
@ -63,6 +53,7 @@ struct Dirty
Dirty *dirty_new(struct Image *image, int x1, int y1, int x2, int y2, int tiled);
Dirty *dirty_new_copy(Dirty *src);
Dirty *dirty_new_from_differences(struct Image *image, struct Image *image_diff);
void dirty_free(Dirty *dirty);
void dirty_putpixel(Dirty *dirty, int x, int y);
@ -76,8 +67,8 @@ void dirty_putpixel_brush(Dirty *dirty, struct Brush *brush, int x, int y);
void dirty_hline_brush(Dirty *dirty, struct Brush *brush, int x1, int y, int x2);
void dirty_line_brush(Dirty *dirty, struct Brush *brush, int x1, int y1, int x2, int y2);
void dirty_get(Dirty *dirty);
void dirty_put(Dirty *dirty);
void dirty_save_image_data(Dirty *dirty);
void dirty_restore_image_data(Dirty *dirty);
void dirty_swap(Dirty *dirty);
#endif /* RASTER_DIRTY_H */

View File

@ -18,6 +18,7 @@
#include "config.h"
#include <assert.h>
#include <string.h>
#include "jinete/jbase.h"
@ -106,8 +107,7 @@ GfxObj *gfxobj_find(unsigned int id)
void _gfxobj_set_id(GfxObj *gfxobj, int id)
{
/* TODO */
/* ji_assert (!gfxobj_find (id)); */
assert(gfxobj_find(id) == NULL);
gfxobj->id = id;
}

View File

@ -26,6 +26,7 @@
#include "raster/algo.h"
#include "raster/blend.h"
#include "raster/brush.h"
#include "raster/image.h"
#ifndef USE_ALLEGRO_IMAGE
@ -276,7 +277,76 @@ void image_ellipsefill(Image *image, int x1, int y1, int x2, int y2, int color)
algo_ellipsefill(x1, y1, x2, y2, &data, (AlgoHLine)hline_for_image);
}
void image_to_allegro(Image *image, struct BITMAP *bmp, int x, int y)
/*********************************************************************
Brushes
*********************************************************************/
/* typedef struct AlgoData */
/* { */
/* Image *image; */
/* Brush *brush; */
/* int color; */
/* } AlgoData; */
/* static void algo_putpixel(int x, int y, AlgoData *data); */
/* static void algo_putbrush(int x, int y, AlgoData *data); */
/* void image_putpixel_brush(Image *image, Brush *brush, int x, int y, int color) */
/* { */
/* AlgoData data = { image, brush, color }; */
/* if (brush->size == 1) */
/* algo_putpixel(x, y, &data); */
/* else */
/* algo_putbrush(x, y, &data); */
/* } */
/* void image_hline_brush(Image *image, Brush *brush, int x1, int y, int x2, int color) */
/* { */
/* AlgoData data = { image, brush, color }; */
/* int x; */
/* if (brush->size == 1) */
/* for (x=x1; x<=x2; ++x) */
/* algo_putpixel(x, y, &data); */
/* else */
/* for (x=x1; x<=x2; ++x) */
/* algo_putbrush(x, y, &data); */
/* } */
/* void image_line_brush(Image *image, Brush *brush, int x1, int y1, int x2, int y2, int color) */
/* { */
/* AlgoData data = { image, brush, color }; */
/* algo_line(x1, y1, x2, y2, &data, */
/* (brush->size == 1)? */
/* (AlgoPixel)algo_putpixel: */
/* (AlgoPixel)algo_putbrush); */
/* } */
/* static void algo_putpixel(int x, int y, AlgoData *data) */
/* { */
/* image_putpixel(data->image, x, y, data->color); */
/* } */
/* static void algo_putbrush(int x, int y, AlgoData *data) */
/* { */
/* register struct BrushScanline *scanline = data->brush->scanline; */
/* register int c = data->brush->size/2; */
/* x -= c; */
/* y -= c; */
/* for (c=0; c<data->brush->size; ++c) { */
/* if (scanline->state) */
/* image_hline(data->image, x+scanline->x1, y+c, x+scanline->x2, data->color); */
/* ++scanline; */
/* } */
/* } */
/*********************************************************************
Allegro <-> Image
*********************************************************************/
void image_to_allegro(Image *image, BITMAP *bmp, int x, int y)
{
image->method->to_allegro(image, bmp, x, y);
}

View File

@ -53,6 +53,16 @@
d.rem = 0; \
}
#define IMAGE_ADDRESS(image,x,y) \
((void *)(image)->line[(y)] + IMAGE_LINE_SIZE((image), (x))) \
#define IMAGE_SHIFT(d) \
(((d)->imgtype == IMAGE_RGB)? 2: \
((d)->imgtype == IMAGE_GRAYSCALE)? 1: 0)
#define IMAGE_LINE_SIZE(image, width) \
((width) << IMAGE_SHIFT(image))
/* Image Types */
enum {
IMAGE_RGB,
@ -62,6 +72,7 @@ enum {
};
struct BITMAP;
/* struct Brush; */
struct ImageMethods;
typedef struct Image Image;
@ -118,6 +129,10 @@ void image_line(Image *image, int x1, int y1, int x2, int y2, int color);
void image_ellipse(Image *image, int x1, int y1, int x2, int y2, int color);
void image_ellipsefill(Image *image, int x1, int y1, int x2, int y2, int color);
/* void image_putpixel_brush(Image *image, struct Brush *brush, int x, int y, int color); */
/* void image_hline_brush(Image *image, struct Brush *brush, int x1, int y, int x2, int color); */
/* void image_line_brush(Image *image, struct Brush *brush, int x1, int y1, int x2, int y2, int color); */
void image_to_allegro(Image *image, struct BITMAP *bmp, int x, int y);
void image_convert(Image *dst, const Image *src);

View File

@ -20,6 +20,7 @@
#include <assert.h>
#include <string.h>
#include <allegro/unicode.h>
#include "jinete/jlist.h"
@ -40,8 +41,9 @@ static void layer_set_parent(Layer *layer, Layer *parent_set);
\
layer->sprite = sprite; \
layer->parent_layer = NULL; \
layer->readable = TRUE; \
layer->writable = TRUE; \
layer->flags = \
LAYER_IS_READABLE | \
LAYER_IS_WRITABLE; \
\
layer->blend_mode = 0; \
layer->cels = NULL; \
@ -153,8 +155,7 @@ Layer *layer_new_copy(Sprite *dst_sprite, const Layer *src_layer)
/* copy general properties */
if (layer_copy != NULL) {
layer_set_name(layer_copy, src_layer->name);
layer_copy->readable = src_layer->readable;
layer_copy->writable = src_layer->writable;
layer_copy->flags = src_layer->flags;
}
return layer_copy;
@ -181,8 +182,6 @@ Layer *layer_new_flatten_copy(Sprite *dst_sprite, const Layer *src_layer,
if (!flat_layer)
return NULL;
layer_set_name(flat_layer, "Flat Layer");
for (frame=frmin; frame<=frmax; frame++) {
/* does this frame have cels to render? */
if (has_cels(src_layer, frame)) {
@ -240,6 +239,54 @@ void layer_free(Layer *layer)
gfxobj_free((GfxObj *)layer);
}
void layer_free_images(Layer *layer)
{
JLink link;
switch (layer->gfxobj.type) {
case GFXOBJ_LAYER_IMAGE:
JI_LIST_FOR_EACH(layer->cels, link) {
Cel *cel = link->data;
if (!cel_is_link(cel, layer)) {
Image *image = layer->sprite->stock->image[cel->image];
assert(image != NULL);
stock_remove_image(layer->sprite->stock, image);
image_free(image);
}
}
break;
case GFXOBJ_LAYER_SET: {
JI_LIST_FOR_EACH(layer->layers, link)
layer_free_images(link->data);
break;
}
}
}
/**
* Configures some properties of the specified layer to make it as the
* "Background" of the sprite.
*
* You can't use this routine if the sprite already has a background
* layer.
*/
void layer_configure_as_background(Layer *layer)
{
assert(layer != NULL);
assert(layer->sprite != NULL);
assert(sprite_get_background_layer(layer->sprite) == NULL);
layer->flags |= LAYER_IS_LOCKMOVE | LAYER_IS_BACKGROUND;
layer_set_name(layer, "Background");
layer_move_layer(layer->sprite->set, layer, NULL);
}
/**
* Returns TRUE if "layer" is a normal layer type (an image layer)
*/
@ -261,7 +308,7 @@ bool layer_is_set(const Layer *layer)
*/
bool layer_is_readable(const Layer *layer)
{
return layer->readable;
return (layer->flags & LAYER_IS_READABLE) == LAYER_IS_READABLE;
}
/**
@ -269,7 +316,23 @@ bool layer_is_readable(const Layer *layer)
*/
bool layer_is_writable(const Layer *layer)
{
return layer->writable;
return (layer->flags & LAYER_IS_WRITABLE) == LAYER_IS_WRITABLE;
}
/**
* Returns TRUE if the layer is moveable.
*/
bool layer_is_moveable(const Layer *layer)
{
return (layer->flags & LAYER_IS_LOCKMOVE) == 0;
}
/**
* Returns TRUE if the layer is the background.
*/
bool layer_is_background(const Layer *layer)
{
return (layer->flags & LAYER_IS_BACKGROUND) == LAYER_IS_BACKGROUND;
}
/**
@ -299,8 +362,7 @@ Layer *layer_get_next(Layer *layer)
void layer_set_name(Layer *layer, const char *name)
{
/* TODO warning overflow */
strcpy(layer->name, name);
ustrzcpy(layer->name, LAYER_NAME_SIZE, name);
}
void layer_set_blend_mode(Layer *layer, int blend_mode)
@ -328,7 +390,7 @@ void layer_remove_cel(Layer *layer, Cel *cel)
jlist_remove(layer->cels, cel);
}
Cel *layer_get_cel(Layer *layer, int frame)
Cel *layer_get_cel(const Layer *layer, int frame)
{
if (layer_is_image(layer)) {
Cel *cel;
@ -374,9 +436,9 @@ void layer_move_layer(Layer *set, Layer *layer, Layer *after)
jlist_prepend(set->layers, layer);
}
void layer_render(Layer *layer, Image *image, int x, int y, int frame)
void layer_render(const Layer *layer, Image *image, int x, int y, int frame)
{
if (!layer->readable)
if (!layer_is_readable(layer))
return;
switch (layer->gfxobj.type) {
@ -417,7 +479,7 @@ void layer_render(Layer *layer, Image *image, int x, int y, int frame)
*/
static bool has_cels(const Layer *layer, int frame)
{
if (!layer->readable)
if (!layer_is_readable(layer))
return FALSE;
switch (layer->gfxobj.type) {

View File

@ -28,6 +28,11 @@ struct Sprite;
#define LAYER_NAME_SIZE 256
#define LAYER_IS_READABLE 0x0001
#define LAYER_IS_WRITABLE 0x0002
#define LAYER_IS_LOCKMOVE 0x0004
#define LAYER_IS_BACKGROUND 0x0008
typedef struct Layer Layer;
struct Layer
@ -37,8 +42,7 @@ struct Layer
struct Sprite *sprite; /* owner of the layer */
/* GfxObj *parent; /\* parent object *\/ */
Layer *parent_layer; /* parent layer */
unsigned readable : 1;
unsigned writable : 1;
unsigned short flags;
/* for GFXOBJ_LAYER_IMAGE */
int blend_mode; /* constant blend mode */
@ -54,10 +58,14 @@ Layer *layer_new_copy(struct Sprite *dst_sprite, const Layer *src_layer);
Layer *layer_new_flatten_copy(struct Sprite *dst_sprite, const Layer *src_layer,
int x, int y, int w, int h, int frmin, int frmax);
void layer_free(Layer *layer);
void layer_free_images(Layer *layer);
void layer_configure_as_background(Layer *layer);
bool layer_is_image(const Layer *layer);
bool layer_is_set(const Layer *layer);
bool layer_is_background(const Layer *layer);
bool layer_is_moveable(const Layer *layer);
bool layer_is_readable(const Layer *layer);
bool layer_is_writable(const Layer *layer);
@ -70,13 +78,13 @@ void layer_set_blend_mode(Layer *layer, int blend_mode);
/* for LAYER_IMAGE */
void layer_add_cel(Layer *layer, struct Cel *cel);
void layer_remove_cel(Layer *layer, struct Cel *cel);
struct Cel *layer_get_cel(Layer *layer, int frame);
struct Cel *layer_get_cel(const Layer *layer, int frame);
/* for LAYER_SET */
void layer_add_layer(Layer *set, Layer *layer);
void layer_remove_layer(Layer *set, Layer *layer);
void layer_move_layer(Layer *set, Layer *layer, Layer *after);
void layer_render(Layer *layer, struct Image *image, int x, int y, int frame);
void layer_render(const Layer *layer, struct Image *image, int x, int y, int frame);
#endif /* RASTER_LAYER_H */

View File

@ -18,6 +18,7 @@
#include "config.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
@ -26,7 +27,7 @@
static void shrink_mask (Mask *mask);
Mask *mask_new (void)
Mask *mask_new(void)
{
Mask *mask = (Mask *)gfxobj_new(GFXOBJ_MASK, sizeof(Mask));
if (!mask)
@ -42,25 +43,25 @@ Mask *mask_new (void)
return mask;
}
Mask *mask_new_copy (const Mask *mask)
Mask *mask_new_copy(const Mask *mask)
{
Mask *copy;
copy = mask_new ();
copy = mask_new();
if (!copy)
return NULL;
mask_copy (copy, mask);
mask_copy(copy, mask);
return copy;
}
void mask_free (Mask *mask)
void mask_free(Mask *mask)
{
if (mask->name)
jfree (mask->name);
jfree(mask->name);
if (mask->bitmap)
image_free (mask->bitmap);
image_free(mask->bitmap);
gfxobj_free((GfxObj *)mask);
}
@ -178,7 +179,7 @@ void mask_union(Mask *mask, int x, int y, int w, int h)
x-mask->x+w-1, y-mask->y+h-1, 1);
}
void mask_subtract (Mask *mask, int x, int y, int w, int h)
void mask_subtract(Mask *mask, int x, int y, int w, int h)
{
if (mask->bitmap) {
image_rectfill(mask->bitmap,
@ -213,6 +214,7 @@ void mask_intersect(Mask *mask, int x, int y, int w, int h)
void mask_merge(Mask *mask, const Mask *src)
{
/* TODO!!! */
assert(FALSE);
}
void mask_by_color(Mask *mask, const Image *src, int color, int fuzziness)
@ -407,7 +409,7 @@ void mask_crop(Mask *mask, const Image *image)
#undef ADVANCE
}
static void shrink_mask (Mask *mask)
static void shrink_mask(Mask *mask)
{
#define SHRINK_SIDE(u_begin, u_op, u_final, u_add, \
v_begin, v_op, v_final, v_add, U, V, var) \

View File

@ -33,24 +33,24 @@ struct Mask
struct Image *bitmap; /* bitmapped image mask */
};
Mask *mask_new (void);
Mask *mask_new_copy (const Mask *mask);
void mask_free (Mask *mask);
Mask *mask_new(void);
Mask *mask_new_copy(const Mask *mask);
void mask_free(Mask *mask);
int mask_is_empty (Mask *mask);
void mask_set_name (Mask *mask, const char *name);
int mask_is_empty(Mask *mask);
void mask_set_name(Mask *mask, const char *name);
void mask_copy (Mask *mask_dst, const Mask *mask_src);
void mask_move (Mask *mask, int x, int y);
void mask_none (Mask *mask);
void mask_invert (Mask *mask);
void mask_replace (Mask *mask, int x, int y, int w, int h);
void mask_union (Mask *mask, int x, int y, int w, int h);
void mask_subtract (Mask *mask, int x, int y, int w, int h);
void mask_intersect (Mask *mask, int x, int y, int w, int h);
void mask_copy(Mask *mask_dst, const Mask *mask_src);
void mask_move(Mask *mask, int x, int y);
void mask_none(Mask *mask);
void mask_invert(Mask *mask);
void mask_replace(Mask *mask, int x, int y, int w, int h);
void mask_union(Mask *mask, int x, int y, int w, int h);
void mask_subtract(Mask *mask, int x, int y, int w, int h);
void mask_intersect(Mask *mask, int x, int y, int w, int h);
void mask_merge (Mask *dst, const Mask *src);
void mask_by_color (Mask *mask, const struct Image *image, int color, int fuzziness);
void mask_crop (Mask *mask, const struct Image *image);
void mask_merge(Mask *dst, const Mask *src);
void mask_by_color(Mask *mask, const struct Image *image, int color, int fuzziness);
void mask_crop(Mask *mask, const struct Image *image);
#endif /* RASTER_MASK_H */

View File

@ -24,6 +24,7 @@
#include "jinete/jlist.h"
#include "jinete/jmutex.h"
#include "file/filedata.h"
#include "modules/palettes.h"
#include "raster/raster.h"
#include "util/boundary.h"
@ -51,7 +52,6 @@ Sprite *sprite_new(int imgtype, int w, int h)
sprite->imgtype = imgtype;
sprite->w = w;
sprite->h = h;
sprite->bgcolor = 0;
sprite->frames = 1;
sprite->frlens = jmalloc(sizeof(int)*sprite->frames);
sprite->frame = 0;
@ -98,6 +98,9 @@ Sprite *sprite_new(int imgtype, int w, int h)
sprite->locked = FALSE;
sprite->mutex = jmutex_new();
/* file format data */
sprite->filedata = NULL;
/* free the temporary palette */
palette_free(pal);
@ -203,8 +206,8 @@ Sprite *sprite_new_with_layer(int imgtype, int w, int h)
/* clear with mask color */
image_clear(image, 0);
/* configure layer name and blend mode */
layer_set_name(layer, "Background");
/* configure the first transparent layer */
layer_set_name(layer, "Layer 1");
layer_set_blend_mode(layer, BLEND_MODE_NORMAL);
/* add image in the layer stock */
@ -275,6 +278,11 @@ void sprite_free(Sprite *sprite)
/* destroy mutex */
jmutex_free(sprite->mutex);
/* destroy file-data */
if (sprite->filedata)
filedata_free(sprite->filedata);
/* destroy gfxobj */
gfxobj_free((GfxObj *)sprite);
}
@ -321,10 +329,8 @@ bool sprite_need_alpha(Sprite *sprite)
switch (sprite->imgtype) {
case IMAGE_RGB:
return _rgba_geta(sprite->bgcolor) < 255;
case IMAGE_GRAYSCALE:
return _graya_geta(sprite->bgcolor) < 255;
return sprite_get_background_layer(sprite) == NULL;
}
return FALSE;
@ -430,6 +436,14 @@ void sprite_set_filename(Sprite *sprite, const char *filename)
strcpy(sprite->filename, filename);
}
void sprite_set_filedata(Sprite *sprite, struct FileData *filedata)
{
if (sprite->filedata)
jfree(sprite->filedata);
sprite->filedata = filedata;
}
void sprite_set_size(Sprite *sprite, int w, int h)
{
sprite->w = w;
@ -518,10 +532,9 @@ void sprite_set_frame(Sprite *sprite, int frame)
*/
void sprite_set_imgtype(Sprite *sprite, int imgtype, int dithering_method)
{
Palette *palette = sprite_get_palette(sprite, 0);
Image *old_image;
Image *new_image;
int c, r, g, b;
int c;
/* nothing to do */
if (sprite->imgtype == imgtype)
@ -531,86 +544,10 @@ void sprite_set_imgtype(Sprite *sprite, int imgtype, int dithering_method)
if (undo_is_enabled(sprite->undo))
undo_open(sprite->undo);
/* change the background color */
if (undo_is_enabled(sprite->undo))
undo_int(sprite->undo, (GfxObj *)sprite, &sprite->bgcolor);
c = sprite->bgcolor;
switch (sprite->imgtype) {
case IMAGE_RGB:
switch (imgtype) {
/* RGB -> Grayscale */
case IMAGE_GRAYSCALE:
r = _rgba_getr(c);
g = _rgba_getg(c);
b = _rgba_getb(c);
rgb_to_hsv_int(&r, &g, &b);
c = _graya(b, _rgba_geta(c));
break;
/* RGB -> Indexed */
case IMAGE_INDEXED:
r = _rgba_getr(c);
g = _rgba_getg(c);
b = _rgba_getb(c);
if (_rgba_geta(c) == 0)
c = 0;
else
c = rgb_map->data[r>>3][g>>3][b>>3];
break;
}
break;
case IMAGE_GRAYSCALE:
switch (imgtype) {
/* Grayscale -> RGB */
case IMAGE_RGB:
g = _graya_getv(c);
c = _rgba(g, g, g, _graya_geta(c));
break;
/* Grayscale -> Indexed */
case IMAGE_INDEXED:
if (_graya_geta(c) == 0)
c = 0;
else
c = _graya_getv(c);
break;
}
break;
case IMAGE_INDEXED:
switch (imgtype) {
/* Indexed -> RGB */
case IMAGE_RGB:
if (c == 0)
c = 0;
else
c = palette->color[c];
break;
/* Indexed -> Grayscale */
case IMAGE_GRAYSCALE:
if (c == 0)
c = 0;
else {
r = _rgba_getr(palette->color[c]);
g = _rgba_getg(palette->color[c]);
b = _rgba_getb(palette->color[c]);
rgb_to_hsv_int(&r, &g, &b);
c = _graya(b, 255);
}
break;
}
break;
}
sprite_set_bgcolor(sprite, c);
/* change imgtype of the stock of images */
if (undo_is_enabled(sprite->undo)) {
undo_int(sprite->undo, (GfxObj *)sprite, &imgtype);
if (undo_is_enabled(sprite->undo))
undo_int(sprite->undo, (GfxObj *)sprite->stock, &sprite->stock->imgtype);
}
sprite->stock->imgtype = imgtype;
for (c=0; c<sprite->stock->nimage; c++) {
@ -624,7 +561,7 @@ void sprite_set_imgtype(Sprite *sprite, int imgtype, int dithering_method)
sprite_get_palette(sprite,
sprite->frame));
if (!new_image)
return; /* TODO big error!!!: not enough memory!
return; /* TODO error handling: not enough memory!
we should undo all work done */
if (undo_is_enabled(sprite->undo))
@ -658,12 +595,18 @@ void sprite_set_imgtype(Sprite *sprite, int imgtype, int dithering_method)
undo_close(sprite->undo);
}
/**
* Sets the background color of the sprite.
*/
void sprite_set_bgcolor(Sprite *sprite, int color)
Layer *sprite_get_background_layer(Sprite *sprite)
{
sprite->bgcolor = color;
assert(sprite != NULL);
if (jlist_length(sprite->set->layers) > 0) {
Layer *bglayer = jlist_last_data(sprite->set->layers);
if (layer_is_background(bglayer))
return bglayer;
}
return NULL;
}
/**
@ -727,7 +670,7 @@ Mask *sprite_request_mask(Sprite *sprite, const char *name)
void sprite_render(Sprite *sprite, Image *image, int x, int y)
{
image_rectfill(image, x, y, x+sprite->w-1, y+sprite->h-1, sprite->bgcolor);
image_rectfill(image, x, y, x+sprite->w-1, y+sprite->h-1, 0);
layer_render(sprite->set, image, x, y, sprite->frame);
}
@ -779,21 +722,31 @@ int sprite_getpixel(Sprite *sprite, int x, int y)
int color = 0;
if ((x >= 0) && (y >= 0) && (x < sprite->w) && (y < sprite->h)) {
int old_bgcolor = sprite->bgcolor;
sprite->bgcolor = 0;
image = image_new(sprite->imgtype, 1, 1);
image_clear(image, 0);
sprite_render(sprite, image, -x, -y);
color = image_getpixel(image, 0, 0);
image_free(image);
sprite->bgcolor = old_bgcolor;
}
return color;
}
int sprite_get_memsize(Sprite *sprite)
{
Image *image;
int i, size = 0;
for (i=0; i<sprite->stock->nimage; i++) {
image = sprite->stock->image[i];
if (image != NULL)
size += IMAGE_LINE_SIZE(image, image->w) * image->h;
}
return size;
}
static Layer *index2layer(Layer *layer, int index, int *index_count)
{
if (index == *index_count)
@ -858,7 +811,6 @@ static Sprite *general_copy(const Sprite *src_sprite)
/* copy general properties */
strcpy(dst_sprite->filename, src_sprite->filename);
sprite_set_bgcolor(dst_sprite, src_sprite->bgcolor);
sprite_set_frames(dst_sprite, src_sprite->frames);
memcpy(dst_sprite->frlens, src_sprite->frlens, sizeof(int)*src_sprite->frames);

View File

@ -22,6 +22,7 @@
#include "jinete/jbase.h"
#include "raster/gfxobj.h"
struct FileData;
struct Image;
struct Layer;
struct Mask;
@ -40,7 +41,6 @@ struct Sprite
to a file in the file-system */
int imgtype; /* image type */
int w, h; /* image width/height size (in pixels) */
int bgcolor; /* background color */
int frames; /* how many frames has this sprite */
int *frlens; /* duration per frame */
int frame; /* current frame, range [0,frames) */
@ -67,6 +67,8 @@ struct Sprite
JMutex mutex; /* mutex to modify the 'locked' flag */
bool locked; /* true when a thread is
reading/writing the sprite */
struct FileData *filedata; /* data to save the file in the same
format that it was loaded */
};
Sprite *sprite_new(int imgtype, int w, int h);
@ -90,6 +92,7 @@ void sprite_set_palette(Sprite *sprite, struct Palette *pal, bool truncate);
void sprite_reset_palettes(Sprite *sprite);
void sprite_set_filename(Sprite *sprite, const char *filename);
void sprite_set_filedata(Sprite *sprite, struct FileData *filedata);
void sprite_set_size(Sprite *sprite, int w, int h);
void sprite_set_frames(Sprite *sprite, int frames);
void sprite_set_frlen(Sprite *sprite, int msecs, int frame);
@ -100,7 +103,8 @@ void sprite_set_mask(Sprite *sprite, const struct Mask *mask);
void sprite_set_layer(Sprite *sprite, struct Layer *layer);
void sprite_set_frame(Sprite *sprite, int frame);
void sprite_set_imgtype(Sprite *sprite, int imgtype, int dithering_method);
void sprite_set_bgcolor(Sprite *sprite, int color);
struct Layer *sprite_get_background_layer(Sprite *sprite);
void sprite_add_path(Sprite *sprite, struct Path *path);
void sprite_remove_path(Sprite *sprite, struct Path *path);
@ -117,4 +121,6 @@ int sprite_layer2index(const Sprite *sprite, const struct Layer *layer);
int sprite_getpixel(Sprite *sprite, int x, int y);
int sprite_get_memsize(Sprite *sprite);
#endif /* RASTER_SPRITE_H */

View File

@ -143,7 +143,7 @@ void stock_remove_image(Stock *stock, Image *image)
*/
void stock_replace_image(Stock *stock, int index, Image *image)
{
/* The zero index can't be changed. */
/* the zero index can't be changed */
if ((index > 0) && (index < stock->nimage))
stock->image[index] = image;
}

View File

@ -22,6 +22,7 @@
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <allegro/config.h>
#include "jinete/jlist.h"
@ -99,6 +100,7 @@ typedef struct UndoChunk
typedef struct UndoStream
{
Undo *undo;
JList chunks;
int size;
} UndoStream;
@ -192,7 +194,7 @@ static UndoAction undo_actions[] = {
/* UndoChunk */
static UndoChunk *undo_chunk_new(int type, int size);
static UndoChunk *undo_chunk_new(UndoStream *stream, int type, int size);
static void undo_chunk_free(UndoChunk *chunk);
/* Raw data */
@ -219,7 +221,7 @@ static int get_raw_mask_size(Mask *mask);
/* UndoStream */
static UndoStream *undo_stream_new(void);
static UndoStream *undo_stream_new(Undo *undo);
static void undo_stream_free(UndoStream *stream);
static UndoChunk *undo_stream_pop_chunk(UndoStream *stream, int tail);
@ -234,12 +236,12 @@ Undo *undo_new(Sprite *sprite)
return NULL;
undo->sprite = sprite;
undo->undo_stream = undo_stream_new();
undo->redo_stream = undo_stream_new();
undo->undo_stream = undo_stream_new(undo);
undo->redo_stream = undo_stream_new(undo);
undo->diff_count = 0;
undo->diff_saved = 0;
undo->enabled = TRUE;
undo->size_limit = 1024*1024;
undo->label = NULL;
return undo;
}
@ -252,6 +254,13 @@ void undo_free(Undo *undo)
jfree(undo);
}
int undo_get_memsize(Undo *undo)
{
return
undo->undo_stream->size +
undo->redo_stream->size;
}
void undo_enable(Undo *undo)
{
undo->enabled = TRUE;
@ -292,6 +301,11 @@ void undo_redo(Undo *undo)
run_undo(undo, DO_REDO, FALSE);
}
void undo_set_label(Undo *undo, const char *label)
{
undo->label = label;
}
const char *undo_get_next_undo_label(Undo *undo)
{
UndoChunk *chunk;
@ -397,6 +411,7 @@ static int count_undo_groups(UndoStream *undo_stream)
static void update_undo(Undo *undo)
{
int groups = count_undo_groups(undo->undo_stream);
int undo_size_limit = get_config_int("Options", "UndoSizeLimit", 8)*1024*1024;
/* more diff */
undo->diff_count++;
@ -404,11 +419,11 @@ static void update_undo(Undo *undo)
/* reset the "redo" stream */
if (!jlist_empty(undo->redo_stream->chunks)) {
undo_stream_free(undo->redo_stream);
undo->redo_stream = undo_stream_new();
undo->redo_stream = undo_stream_new(undo);
}
/* "undo" is too big? */
while (groups > 1 && undo->undo_stream->size > undo->size_limit) {
while (groups > 1 && undo->undo_stream->size > undo_size_limit) {
run_undo(undo, DO_UNDO, TRUE);
groups--;
}
@ -430,10 +445,9 @@ void undo_open(Undo *undo)
static void chunk_open_new(UndoStream *stream)
{
UndoChunk *chunk = undo_chunk_new(UNDO_TYPE_OPEN,
sizeof(UndoChunk));
undo_stream_push_chunk(stream, chunk);
undo_chunk_new(stream,
UNDO_TYPE_OPEN,
sizeof(UndoChunk));
}
static void chunk_open_invert(UndoStream *stream, UndoChunk *chunk, int state)
@ -457,10 +471,9 @@ void undo_close(Undo *undo)
static void chunk_close_new(UndoStream *stream)
{
UndoChunk *chunk = undo_chunk_new(UNDO_TYPE_CLOSE,
sizeof(UndoChunk));
undo_stream_push_chunk(stream, chunk);
undo_chunk_new(stream,
UNDO_TYPE_CLOSE,
sizeof(UndoChunk));
}
static void chunk_close_invert(UndoStream *stream, UndoChunk *chunk, int state)
@ -483,8 +496,8 @@ struct UndoChunkData
{
UndoChunk head;
ase_uint32 gfxobj_id;
ase_uint32 offset;
ase_uint32 size;
ase_uint32 dataoffset;
ase_uint32 datasize;
ase_uint8 data[0];
};
@ -503,23 +516,22 @@ static void chunk_data_new(UndoStream *stream, GfxObj *gfxobj, void *data, int s
assert(size >= 1);
chunk = (UndoChunkData *)
undo_chunk_new(UNDO_TYPE_DATA,
undo_chunk_new(stream,
UNDO_TYPE_DATA,
sizeof(UndoChunkData)+size);
chunk->gfxobj_id = gfxobj->id;
chunk->offset = offset;
chunk->size = size;
chunk->dataoffset = offset;
chunk->datasize = size;
memcpy(chunk->data, data, size);
undo_stream_push_chunk(stream, (UndoChunk *)chunk);
}
static void chunk_data_invert(UndoStream *stream, UndoChunkData *chunk, int state)
{
unsigned int id = chunk->gfxobj_id;
unsigned int offset = chunk->offset;
unsigned int size = chunk->size;
unsigned int offset = chunk->dataoffset;
unsigned int size = chunk->datasize;
GfxObj *gfxobj = gfxobj_find(id);
if (gfxobj) {
@ -575,7 +587,8 @@ static void chunk_image_new(UndoStream *stream, Image *image, int x, int y, int
size = IMAGE_LINE_SIZE(image, w);
chunk = (UndoChunkImage *)
undo_chunk_new(UNDO_TYPE_IMAGE,
undo_chunk_new(stream,
UNDO_TYPE_IMAGE,
sizeof(UndoChunkImage) + size*h);
chunk->image_id = image->gfxobj.id;
@ -591,8 +604,6 @@ static void chunk_image_new(UndoStream *stream, Image *image, int x, int y, int
memcpy(ptr, IMAGE_ADDRESS(image, x, y+v), size);
ptr += size;
}
undo_stream_push_chunk(stream, (UndoChunk *)chunk);
}
/* static void chunk_image_free(UndoChunkImage *chunk) */
@ -660,7 +671,8 @@ void undo_flip(Undo *undo, Image *image, int x1, int y1, int x2, int y2, int hor
static void chunk_flip_new(UndoStream *stream, Image *image, int x1, int y1, int x2, int y2, int horz)
{
UndoChunkFlip *chunk = (UndoChunkFlip *)
undo_chunk_new(UNDO_TYPE_FLIP,
undo_chunk_new(stream,
UNDO_TYPE_FLIP,
sizeof(UndoChunkFlip));
chunk->image_id = image->gfxobj.id;
@ -670,8 +682,6 @@ static void chunk_flip_new(UndoStream *stream, Image *image, int x1, int y1, int
chunk->x2 = x2;
chunk->y2 = y2;
chunk->horz = horz;
undo_stream_push_chunk(stream, (UndoChunk *)chunk);
}
static void chunk_flip_invert(UndoStream *stream, UndoChunkFlip *chunk, int state)
@ -727,12 +737,11 @@ void undo_dirty(Undo *undo, Dirty *dirty)
static void chunk_dirty_new(UndoStream *stream, Dirty *dirty)
{
UndoChunkDirty *chunk = (UndoChunkDirty *)
undo_chunk_new(UNDO_TYPE_DIRTY,
undo_chunk_new(stream,
UNDO_TYPE_DIRTY,
sizeof(UndoChunkDirty)+get_raw_dirty_size(dirty));
write_raw_dirty(chunk->data, dirty);
undo_stream_push_chunk(stream, (UndoChunk *)chunk);
}
static void chunk_dirty_invert(UndoStream *stream, UndoChunkDirty *chunk, int state)
@ -762,6 +771,10 @@ struct UndoChunkAddImage
ase_uint32 index;
};
/* TODO fix this so it doesn't need to be called as:
image_index = stock_add_image(sprite->stock, image);
undo_add_image(sprite->undo, sprite->stock, image);
*/
void undo_add_image(Undo *undo, Stock *stock, Image *image)
{
chunk_add_image_new(undo->undo_stream, stock, image);
@ -771,7 +784,8 @@ void undo_add_image(Undo *undo, Stock *stock, Image *image)
static void chunk_add_image_new(UndoStream *stream, Stock *stock, Image *image)
{
UndoChunkAddImage *chunk = (UndoChunkAddImage *)
undo_chunk_new(UNDO_TYPE_ADD_IMAGE,
undo_chunk_new(stream,
UNDO_TYPE_ADD_IMAGE,
sizeof(UndoChunkAddImage));
int index;
@ -781,8 +795,6 @@ static void chunk_add_image_new(UndoStream *stream, Stock *stock, Image *image)
chunk->stock_id = stock->gfxobj.id;
chunk->index = index;
undo_stream_push_chunk(stream, (UndoChunk *)chunk);
}
static void chunk_add_image_invert(UndoStream *stream, UndoChunkAddImage *chunk, int state)
@ -828,7 +840,8 @@ void undo_remove_image(Undo *undo, Stock *stock, Image *image)
static void chunk_remove_image_new(UndoStream *stream, Stock *stock, Image *image)
{
UndoChunkRemoveImage *chunk = (UndoChunkRemoveImage *)
undo_chunk_new(UNDO_TYPE_REMOVE_IMAGE,
undo_chunk_new(stream,
UNDO_TYPE_REMOVE_IMAGE,
sizeof(UndoChunkRemoveImage)+get_raw_image_size(image));
int index;
@ -840,8 +853,6 @@ static void chunk_remove_image_new(UndoStream *stream, Stock *stock, Image *imag
chunk->index = index;
write_raw_image(chunk->data, image);
undo_stream_push_chunk(stream, (UndoChunk *)chunk);
}
static void chunk_remove_image_invert(UndoStream *stream, UndoChunkRemoveImage *chunk, int state)
@ -888,15 +899,14 @@ static void chunk_replace_image_new(UndoStream *stream, Stock *stock, int index)
{
Image *image = stock->image[index];
UndoChunkReplaceImage *chunk = (UndoChunkReplaceImage *)
undo_chunk_new(UNDO_TYPE_REPLACE_IMAGE,
undo_chunk_new(stream,
UNDO_TYPE_REPLACE_IMAGE,
sizeof(UndoChunkReplaceImage)+get_raw_image_size(image));
chunk->stock_id = stock->gfxobj.id;
chunk->index = index;
write_raw_image(chunk->data, image);
undo_stream_push_chunk(stream, (UndoChunk *)chunk);
}
static void chunk_replace_image_invert(UndoStream *stream, UndoChunkReplaceImage *chunk, int state)
@ -942,13 +952,12 @@ void undo_add_cel(Undo *undo, Layer *layer, Cel *cel)
static void chunk_add_cel_new(UndoStream *stream, Layer *layer, Cel *cel)
{
UndoChunkAddCel *chunk = (UndoChunkAddCel *)
undo_chunk_new(UNDO_TYPE_ADD_CEL,
undo_chunk_new(stream,
UNDO_TYPE_ADD_CEL,
sizeof(UndoChunkAddCel));
chunk->layer_id = layer->gfxobj.id;
chunk->cel_id = cel->gfxobj.id;
undo_stream_push_chunk(stream, (UndoChunk *)chunk);
}
static void chunk_add_cel_invert(UndoStream *stream, UndoChunkAddCel *chunk, int state)
@ -989,13 +998,12 @@ void undo_remove_cel(Undo *undo, Layer *layer, Cel *cel)
static void chunk_remove_cel_new(UndoStream *stream, Layer *layer, Cel *cel)
{
UndoChunkRemoveCel *chunk = (UndoChunkRemoveCel *)
undo_chunk_new(UNDO_TYPE_REMOVE_CEL,
undo_chunk_new(stream,
UNDO_TYPE_REMOVE_CEL,
sizeof(UndoChunkRemoveCel)+get_raw_cel_size(cel));
chunk->layer_id = layer->gfxobj.id;
write_raw_cel(chunk->data, cel);
undo_stream_push_chunk(stream, (UndoChunk *)chunk);
}
static void chunk_remove_cel_invert(UndoStream *stream, UndoChunkRemoveCel *chunk, int state)
@ -1038,13 +1046,12 @@ void undo_add_layer(Undo *undo, Layer *set, Layer *layer)
static void chunk_add_layer_new(UndoStream *stream, Layer *set, Layer *layer)
{
UndoChunkAddLayer *chunk = (UndoChunkAddLayer *)
undo_chunk_new(UNDO_TYPE_ADD_LAYER,
undo_chunk_new(stream,
UNDO_TYPE_ADD_LAYER,
sizeof(UndoChunkAddLayer));
chunk->set_id = set->gfxobj.id;
chunk->layer_id = layer->gfxobj.id;
undo_stream_push_chunk(stream, (UndoChunk *)chunk);
}
static void chunk_add_layer_invert(UndoStream *stream, UndoChunkAddLayer *chunk, int state)
@ -1056,6 +1063,7 @@ static void chunk_add_layer_invert(UndoStream *stream, UndoChunkAddLayer *chunk,
chunk_remove_layer_new(stream, layer);
layer_remove_layer(set, layer);
layer_free_images(layer);
layer_free(layer);
}
}
@ -1087,7 +1095,8 @@ void undo_remove_layer(Undo *undo, Layer *layer)
static void chunk_remove_layer_new(UndoStream *stream, Layer *layer)
{
UndoChunkRemoveLayer *chunk = (UndoChunkRemoveLayer *)
undo_chunk_new(UNDO_TYPE_REMOVE_LAYER,
undo_chunk_new(stream,
UNDO_TYPE_REMOVE_LAYER,
sizeof(UndoChunkRemoveLayer)+get_raw_layer_size(layer));
Layer *set = layer->parent_layer;
Layer *after = layer_get_prev(layer);
@ -1095,8 +1104,6 @@ static void chunk_remove_layer_new(UndoStream *stream, Layer *layer)
chunk->set_id = set->gfxobj.id;
chunk->after_id = after ? after->gfxobj.id: 0;
write_raw_layer(chunk->data, layer);
undo_stream_push_chunk(stream, (UndoChunk *)chunk);
}
static void chunk_remove_layer_invert(UndoStream *stream, UndoChunkRemoveLayer *chunk, int state)
@ -1142,7 +1149,8 @@ void undo_move_layer(Undo *undo, Layer *layer)
static void chunk_move_layer_new(UndoStream *stream, Layer *layer)
{
UndoChunkMoveLayer *chunk = (UndoChunkMoveLayer *)
undo_chunk_new(UNDO_TYPE_MOVE_LAYER,
undo_chunk_new(stream,
UNDO_TYPE_MOVE_LAYER,
sizeof(UndoChunkMoveLayer));
Layer *set = layer->parent_layer;
Layer *after = layer_get_prev(layer);
@ -1150,8 +1158,6 @@ static void chunk_move_layer_new(UndoStream *stream, Layer *layer)
chunk->set_id = set->gfxobj.id;
chunk->layer_id = layer->gfxobj.id;
chunk->after_id = after ? after->gfxobj.id: 0;
undo_stream_push_chunk(stream, (UndoChunk *)chunk);
}
static void chunk_move_layer_invert(UndoStream *stream, UndoChunkMoveLayer *chunk, int state)
@ -1191,13 +1197,12 @@ void undo_set_layer(Undo *undo, Sprite *sprite)
static void chunk_set_layer_new(UndoStream *stream, Sprite *sprite)
{
UndoChunkSetLayer *chunk = (UndoChunkSetLayer *)
undo_chunk_new(UNDO_TYPE_SET_LAYER,
undo_chunk_new(stream,
UNDO_TYPE_SET_LAYER,
sizeof(UndoChunkSetLayer));
chunk->sprite_id = sprite->gfxobj.id;
chunk->layer_id = sprite->layer ? sprite->layer->gfxobj.id: 0;
undo_stream_push_chunk(stream, (UndoChunk *)chunk);
}
static void chunk_set_layer_invert(UndoStream *stream, UndoChunkSetLayer *chunk, int state)
@ -1237,13 +1242,12 @@ void undo_set_mask(Undo *undo, Sprite *sprite)
static void chunk_set_mask_new(UndoStream *stream, Sprite *sprite)
{
UndoChunkSetMask *chunk = (UndoChunkSetMask *)
undo_chunk_new(UNDO_TYPE_SET_MASK,
undo_chunk_new(stream,
UNDO_TYPE_SET_MASK,
sizeof(UndoChunkSetMask)+get_raw_mask_size(sprite->mask));
chunk->sprite_id = sprite->gfxobj.id;
write_raw_mask(chunk->data, sprite->mask);
undo_stream_push_chunk(stream, (UndoChunk *)chunk);
}
static void chunk_set_mask_invert(UndoStream *stream, UndoChunkSetMask *chunk, int state)
@ -1285,13 +1289,12 @@ void undo_set_frames(Undo *undo, Sprite *sprite)
static void chunk_set_frames_new(UndoStream *stream, Sprite *sprite)
{
UndoChunkSetFrames *chunk = (UndoChunkSetFrames *)
undo_chunk_new(UNDO_TYPE_SET_FRAMES,
undo_chunk_new(stream,
UNDO_TYPE_SET_FRAMES,
sizeof(UndoChunkSetFrames));
chunk->sprite_id = sprite->gfxobj.id;
chunk->frames = sprite->frames;
undo_stream_push_chunk(stream, (UndoChunk *)chunk);
}
static void chunk_set_frames_invert(UndoStream *stream, UndoChunkSetFrames *chunk, int state)
@ -1310,7 +1313,7 @@ static void chunk_set_frames_invert(UndoStream *stream, UndoChunkSetFrames *chun
***********************************************************************/
static UndoChunk *undo_chunk_new(int type, int size)
static UndoChunk *undo_chunk_new(UndoStream *stream, int type, int size)
{
UndoChunk *chunk;
@ -1322,8 +1325,11 @@ static UndoChunk *undo_chunk_new(int type, int size)
chunk->type = type;
chunk->size = size;
chunk->label = undo_actions[chunk->type].name;
chunk->label = stream->undo->label ?
stream->undo->label:
undo_actions[chunk->type].name;
undo_stream_push_chunk(stream, chunk);
return chunk;
}
@ -1653,7 +1659,7 @@ static Layer *read_raw_layer(ase_uint8 *raw_data)
read_raw_uint32(layer_id); /* ID */
read_raw_data(name, LAYER_NAME_SIZE); /* name */
read_raw_uint8(flags); /* properties */
read_raw_uint8(flags); /* flags */
read_raw_uint16(layer_type); /* type */
read_raw_uint32(sprite_id); /* sprite */
@ -1675,10 +1681,24 @@ static Layer *read_raw_layer(ase_uint8 *raw_data)
/* read cels */
for (c=0; c<cels; c++) {
Cel *cel = read_raw_cel(raw_data);
Cel *cel;
bool as_image;
/* read the cel */
cel = read_raw_cel(raw_data);
raw_data += get_raw_cel_size(cel);
/* add the cel in the layer */
layer_add_cel(layer, cel);
raw_data += get_raw_cel_size(cel);
/* read the image */
read_raw_uint8(as_image);
if (as_image) {
Image *image = read_raw_image(raw_data);
raw_data += get_raw_image_size(image);
stock_replace_image(layer->sprite->stock, cel->image, image);
}
}
break;
}
@ -1708,9 +1728,7 @@ static Layer *read_raw_layer(ase_uint8 *raw_data)
if (layer != NULL) {
layer_set_name(layer, name);
layer->readable = (flags & 1) ? TRUE: FALSE;
layer->writable = (flags & 2) ? TRUE: FALSE;
layer->flags = flags;
_gfxobj_set_id((GfxObj *)layer, layer_id);
}
@ -1726,20 +1744,31 @@ static ase_uint8 *write_raw_layer(ase_uint8 *raw_data, Layer *layer)
write_raw_uint32(layer->gfxobj.id); /* ID */
write_raw_data(layer->name, LAYER_NAME_SIZE); /* name */
write_raw_uint8(((layer->readable)?1:0) |
(((layer->writable)?1:0)<<1)); /* properties */
write_raw_uint8(layer->flags); /* flags */
write_raw_uint16(layer->gfxobj.type); /* type */
write_raw_uint32(layer->sprite->gfxobj.id); /* sprite */
switch (layer->gfxobj.type) {
case GFXOBJ_LAYER_IMAGE:
/* properties */
write_raw_uint8(layer->blend_mode); /* blend mode */
/* blend mode */
write_raw_uint8(layer->blend_mode);
/* cels */
write_raw_uint16(jlist_length(layer->cels));
JI_LIST_FOR_EACH(layer->cels, link) {
raw_data = write_raw_cel(raw_data, link->data);
Cel *cel = link->data;
raw_data = write_raw_cel(raw_data, cel);
if (cel_is_link(cel, layer)) {
write_raw_uint8(0);
}
else {
Image *image = layer->sprite->stock->image[cel->image];
assert(image != NULL);
write_raw_uint8(1);
raw_data = write_raw_image(raw_data, image);
}
}
break;
@ -1766,7 +1795,13 @@ static int get_raw_layer_size(Layer *layer)
size += 1; /* blend mode */
size += 2; /* num of cels */
JI_LIST_FOR_EACH(layer->cels, link) {
size += get_raw_cel_size(link->data);
Cel *cel = link->data;
size += get_raw_cel_size(cel);
size++; /* has image? */
if (!cel_is_link(cel, layer)) {
Image *image = layer->sprite->stock->image[cel->image];
size += get_raw_image_size(image);
}
}
break;
@ -1846,11 +1881,11 @@ static int get_raw_mask_size(Mask *mask)
/***********************************************************************
Helper routines for UndoStream (a serie of chunks)
Helper routines for UndoStream (a serie of UndoChunks)
***********************************************************************/
static UndoStream *undo_stream_new(void)
static UndoStream *undo_stream_new(Undo *undo)
{
UndoStream *stream;
@ -1858,6 +1893,7 @@ static UndoStream *undo_stream_new(void)
if (!stream)
return NULL;
stream->undo = undo;
stream->chunks = jlist_new();
stream->size = 0;

View File

@ -43,12 +43,15 @@ struct Undo
int diff_count;
int diff_saved;
unsigned enabled : 1; /* is undo enabled? */
int size_limit; /* limit for undo stream size */
const char *label; /* current label to be applied to all
next undo operations */
};
Undo *undo_new(struct Sprite *sprite);
void undo_free(Undo *undo);
int undo_get_memsize(Undo *undo);
void undo_enable(Undo *undo);
void undo_disable(Undo *undo);
@ -61,6 +64,7 @@ bool undo_can_redo(Undo *undo);
void undo_undo(Undo *undo);
void undo_redo(Undo *undo);
void undo_set_label(Undo *undo, const char *label);
const char *undo_get_next_undo_label(Undo *undo);
const char *undo_get_next_redo_label(Undo *undo);
@ -88,7 +92,4 @@ void undo_set_frames(Undo *undo, struct Sprite *sprite);
#define undo_double(undo, gfxobj, value_address) \
undo_data((undo), (gfxobj), (void *)(value_address), sizeof(double))
#define undo_string(undo, gfxobj, string) \
undo_data((undo), (gfxobj), (void *)(string), strlen(string)+1)
#endif /* RASTER_UNDO_H */

View File

@ -253,9 +253,11 @@ static int metatable_index(lua_State *L)
else if (strcmp(index, "parent") == 0)
push_userdata(L, Type_Layer, layer->parent_layer);
else if (strcmp(index, "readable") == 0)
lua_pushboolean(L, layer->readable);
lua_pushboolean(L, layer_is_readable(layer));
else if (strcmp(index, "writable") == 0)
lua_pushboolean(L, layer->writable);
lua_pushboolean(L, layer_is_writable(layer));
else if (strcmp(index, "moveable") == 0)
lua_pushboolean(L, layer_is_moveable(layer));
else if (strcmp(index, "prev") == 0)
push_userdata(L, Type_Layer, layer_get_prev(layer));
else if (strcmp(index, "next") == 0)

View File

@ -26,20 +26,19 @@
#include "file/file.h"
#include "modules/gui.h"
#include "modules/sprites.h"
#include "raster/blend.h"
#include "raster/cel.h"
#include "raster/image.h"
#include "raster/layer.h"
#include "raster/sprite.h"
#include "raster/stock.h"
#include "raster/undo.h"
#include "raster/raster.h"
#include "util/misc.h"
#include "widgets/colbar.h"
/*===================================================================*/
/* Sprite */
/*===================================================================*/
static void displace_layers(Undo *undo, Layer *layer, int x, int y);
/**
* Creates a new sprite with the given dimension.
* Creates a new sprite with the given dimension with one transparent
* layer called "Layer 1".
*
* @param imgtype Color mode, one of the following values: IMAGE_RGB, IMAGE_GRAYSCALE, IMAGE_INDEXED
* @param w Width of the sprite
@ -142,12 +141,79 @@ void SetSprite(Sprite *sprite)
set_current_sprite(sprite);
}
void CropSprite(void)
{
Sprite *sprite = current_sprite;
if ((sprite) &&
(!mask_is_empty(sprite->mask))) {
if (undo_is_enabled(sprite->undo)) {
undo_open(sprite->undo);
undo_int(sprite->undo, (GfxObj *)sprite, &sprite->w);
undo_int(sprite->undo, (GfxObj *)sprite, &sprite->h);
}
sprite_set_size(sprite, sprite->mask->w, sprite->mask->h);
displace_layers(sprite->undo, sprite->set,
-sprite->mask->x, -sprite->mask->y);
if (undo_is_enabled(sprite->undo)) {
undo_int(sprite->undo, (GfxObj *)sprite->mask, &sprite->mask->x);
undo_int(sprite->undo, (GfxObj *)sprite->mask, &sprite->mask->y);
}
sprite->mask->x = 0;
sprite->mask->y = 0;
if (undo_is_enabled(sprite->undo))
undo_close(sprite->undo);
sprite_generate_mask_boundaries(sprite);
update_screen_for_sprite(sprite);
}
}
/**
* Moves every frame in "layer" with the offset "x"/"y".
*/
static void displace_layers(Undo *undo, Layer *layer, int x, int y)
{
switch (layer->gfxobj.type) {
case GFXOBJ_LAYER_IMAGE: {
Cel *cel;
JLink link;
JI_LIST_FOR_EACH(layer->cels, link) {
cel = link->data;
if (undo_is_enabled(undo)) {
undo_int(undo, (GfxObj *)cel, &cel->x);
undo_int(undo, (GfxObj *)cel, &cel->y);
}
cel->x += x;
cel->y += y;
}
break;
}
case GFXOBJ_LAYER_SET: {
JLink link;
JI_LIST_FOR_EACH(layer->layers, link)
displace_layers(undo, link->data, x, y);
break;
}
}
}
/*===================================================================*/
/* Layer */
/*===================================================================*/
static int count_layers(Layer *layer);
static void undo_remove_stock_images(Layer *layer);
static int get_max_layer_num(Layer *layer);
/**
* Creates a new layer with one cel in the current frame of the
@ -296,16 +362,13 @@ void RemoveLayer(void)
undo_set_layer(sprite->undo, sprite);
sprite_set_layer(sprite, layer_select);
/* remove all the images of this layer from the stock */
if (undo_is_enabled(sprite->undo))
undo_remove_stock_images(layer);
/* remove the layer */
if (undo_is_enabled(sprite->undo))
undo_remove_layer(sprite->undo, layer);
layer_remove_layer(parent, layer);
/* destroy the layer */
layer_free_images(layer);
layer_free(layer);
/* close undo */
@ -319,7 +382,7 @@ char *GetUniqueLayerName(void)
Sprite *sprite = current_sprite;
if (sprite) {
char buf[1024];
sprintf(buf, "%s %d", _("Layer"), count_layers(sprite->set));
sprintf(buf, "Layer %d", get_max_layer_num(sprite->set)+1);
return jstrdup(buf);
}
else
@ -328,101 +391,375 @@ char *GetUniqueLayerName(void)
Layer *FlattenLayers(void)
{
Sprite *sprite = current_sprite;
bool is_new_background = FALSE;
JLink link, next;
Layer *flat_layer;
Sprite *sprite;
Layer *background;
Image *image;
Image *cel_image;
Cel *cel;
int frame;
int bgcolor;
sprite = current_sprite;
/* there are a current sprite selected? */
if (!sprite)
return NULL;
/* generate the flat_layer */
flat_layer = layer_new_flatten_copy(sprite, sprite->set,
0, 0, sprite->w, sprite->h,
0, sprite->frames-1);
if (!flat_layer) {
/* create a temporary image */
image = image_new(sprite->imgtype, sprite->w, sprite->h);
if (!image) {
console_printf("Not enough memory");
return NULL;
}
/* open undo, and add the new layer */
if (undo_is_enabled(sprite->undo)) {
/* get the background layer from the sprite */
background = sprite_get_background_layer(sprite);
if (!background) {
/* if there aren't a background layer we must to create the background */
background = layer_new(sprite);
if (!background) {
image_free(image);
console_printf("Not enough memory");
return NULL;
}
layer_configure_as_background(background);
is_new_background = TRUE;
/* get the color to clean the temporary image in each frame */
bgcolor = get_color_for_image(sprite->imgtype,
colorbar_get_bg_color(app_get_colorbar()));
}
else
bgcolor = 0;
/* open undo */
if (undo_is_enabled(sprite->undo))
undo_open(sprite->undo);
undo_add_layer(sprite->undo, sprite->set, flat_layer);
/* add the new layer */
if (is_new_background) {
if (undo_is_enabled(sprite->undo))
undo_add_layer(sprite->undo, sprite->set, background);
layer_add_layer(sprite->set, background);
}
layer_add_layer(sprite->set, flat_layer);
/* copy all frames to the background */
for (frame=0; frame<sprite->frames; frame++) {
/* clear the image and render this frame */
image_clear(image, bgcolor);
layer_render(sprite->set, image, 0, 0, frame);
/* select the new layer */
if (undo_is_enabled(sprite->undo))
undo_set_layer(sprite->undo, sprite);
cel = layer_get_cel(background, frame);
if (cel) {
cel_image = sprite->stock->image[cel->image];
assert(cel_image != NULL);
sprite_set_layer(sprite, flat_layer);
/* we have to save the current state of `cel_image' in the undo */
if (undo_is_enabled(sprite->undo)) {
Dirty *dirty = dirty_new_from_differences(cel_image, image);
dirty_save_image_data(dirty);
/* TODO error handling: if (dirty == NULL) */
if (dirty != NULL)
undo_dirty(sprite->undo, dirty);
}
}
else {
/* if there aren't a cel in this frame in the background, we
have to create a copy of the image for the new cel which will
be created */
cel_image = image_new_copy(image);
/* TODO error handling: if (!cel_image) { ... } */
/* here we create the new cel (with the new image `cel_image') */
cel = cel_new(frame, stock_add_image(sprite->stock, cel_image));
/* TODO error handling: if (!cel) { ... } */
/* and finally we add the cel in the background */
layer_add_cel(background, cel);
}
image_copy(cel_image, image, 0, 0);
}
/* select the background */
if (sprite->layer != background) {
if (undo_is_enabled(sprite->undo))
undo_set_layer(sprite->undo, sprite);
sprite_set_layer(sprite, background);
}
/* remove old layers */
JI_LIST_FOR_EACH_SAFE(sprite->set->layers, link, next) {
if (link->data != flat_layer) {
if (link->data != background) {
Layer *old_layer = link->data;
/* undo */
/* remove the layer */
if (undo_is_enabled(sprite->undo))
undo_remove_layer(sprite->undo, old_layer);
/* remove and destroy this layer */
layer_remove_layer(sprite->set, old_layer);
/* destroy the layer */
layer_free_images(old_layer);
layer_free(old_layer);
}
}
/* destroy the temporary image */
image_free(image);
/* close the undo */
if (undo_is_enabled(sprite->undo))
undo_close(sprite->undo);
#if 0 /* TODO why? */
/* update all editors that has this sprite */
update_screen_for_sprite(sprite);
#endif
return background;
}
return flat_layer;
void CropLayer(void)
{
Sprite *sprite = current_sprite;
if ((sprite != NULL) &&
(!mask_is_empty(sprite->mask)) &&
(sprite->layer != NULL) &&
(layer_is_image(sprite->layer))) {
Layer *layer = sprite->layer;
Cel *cel;
Image *image;
Layer *new_layer;
Cel *new_cel;
Image *new_image;
Layer *set = layer->parent_layer;
JLink link;
new_layer = layer_new(sprite);
if (!new_layer) {
console_printf(_("Not enough memory\n"));
return;
}
layer_set_name(new_layer, layer->name);
layer_set_blend_mode(new_layer, layer->blend_mode);
JI_LIST_FOR_EACH(layer->cels, link) {
cel = link->data;
image = stock_get_image(sprite->stock, cel->image);
if (!image)
continue;
new_cel = cel_new_copy(cel);
if (!new_cel) {
layer_free(new_layer);
console_printf(_("Not enough memory\n"));
return;
}
new_image = image_crop(image,
sprite->mask->x-cel->x,
sprite->mask->y-cel->y,
sprite->mask->w,
sprite->mask->h);
if (!new_image) {
layer_free(new_layer);
cel_free(new_cel);
console_printf(_("Not enough memory\n"));
return;
}
new_cel->image = stock_add_image(sprite->stock, new_image);
new_cel->x = sprite->mask->x;
new_cel->y = sprite->mask->y;
layer_add_cel(new_layer, new_cel);
}
/* add the new layer */
if (undo_is_enabled(sprite->undo)) {
undo_open(sprite->undo);
undo_add_layer(sprite->undo, set, new_layer);
}
layer_add_layer(set, new_layer);
/* move it after the old one */
if (undo_is_enabled(sprite->undo))
undo_move_layer(sprite->undo, new_layer);
layer_move_layer(set, new_layer, layer);
/* set the new one as the current one */
if (undo_is_enabled(sprite->undo))
undo_set_layer(sprite->undo, sprite);
sprite_set_layer(sprite, new_layer);
/* remove the old layer */
if (undo_is_enabled(sprite->undo)) {
undo_remove_layer(sprite->undo, layer);
undo_close(sprite->undo);
}
layer_remove_layer(set, layer);
layer_free_images(layer);
layer_free(layer);
/* refresh */
update_screen_for_sprite(sprite);
}
}
/**
* Converts the selected layer in a `Background' layer.
*/
void BackgroundFromLayer(void)
{
Sprite *sprite;
int bgcolor;
JLink link;
Image *bg_image;
Image *cel_image;
sprite = current_sprite;
if (sprite == NULL) {
console_printf("LayerFromBackground: there are not a current sprite selected\n");
return;
}
if (sprite_get_background_layer(sprite) != NULL) {
console_printf("LayerFromBackground: the current sprite already has a `Background' layer.\n");
return;
}
if (sprite->layer == NULL) {
console_printf("LayerFromBackground: there are not a current layer selected.\n");
return;
}
if (!layer_is_image(sprite->layer)) {
console_printf("LayerFromBackground: the current layer must be a `image' layer.\n");
return;
}
if (!layer_is_readable(sprite->layer)) {
console_printf("LayerFromBackground: the current layer is hidden, can't be converted.\n");
return;
}
if (!layer_is_writable(sprite->layer)) {
console_printf("LayerFromBackground: the current layer is locked, can't be converted.\n");
return;
}
/* each frame of the layer to be converted as `Background' must be
cleared using the selected background color in the color-bar */
bgcolor = app_get_bg_color(sprite);
if (undo_is_enabled(sprite->undo))
undo_open(sprite->undo);
/* create a temporary image to draw each frame of the new
`Background' layer */
bg_image = image_new(sprite->imgtype, sprite->w, sprite->h);
JI_LIST_FOR_EACH(sprite->layer->cels, link) {
Cel *cel = link->data;
assert((cel->image >= 0) &&
(cel->image < sprite->stock->nimage));
/* get the image from the sprite's stock of images */
cel_image = sprite->stock->image[cel->image];
assert(cel_image != NULL);
image_clear(bg_image, bgcolor);
image_merge(bg_image, cel_image,
cel->x,
cel->y,
MID(0, cel->opacity, 255),
sprite->layer->blend_mode);
/* now we have to copy the new image (bg_image) to the cel... */
if (undo_is_enabled(sprite->undo)) {
if (cel->x != 0) undo_int(sprite->undo, (GfxObj *)cel, &cel->x);
if (cel->y != 0) undo_int(sprite->undo, (GfxObj *)cel, &cel->y);
}
/* same size of cel-image and bg-image */
if (bg_image->w == cel_image->w &&
bg_image->h == cel_image->h) {
if (undo_is_enabled(sprite->undo))
undo_image(sprite->undo, cel_image, 0, 0, cel_image->w, cel_image->h);
image_copy(cel_image, bg_image, 0, 0);
}
else {
if (undo_is_enabled(sprite->undo))
undo_replace_image(sprite->undo, sprite->stock, cel->image);
/* replace the image */
sprite->stock->image[cel->image] = image_new_copy(bg_image);
image_free(cel_image);
}
/* change the cel position */
cel->x = 0;
cel->y = 0;
}
image_free(bg_image);
/* new configuration for the `Background' layer */
if (undo_is_enabled(sprite->undo)) {
undo_data(sprite->undo,
(GfxObj *)sprite->layer,
&sprite->layer->flags,
sizeof(sprite->layer->flags));
undo_data(sprite->undo,
(GfxObj *)sprite->layer,
&sprite->layer->name,
LAYER_NAME_SIZE);
undo_move_layer(sprite->undo, sprite->layer);
}
layer_configure_as_background(sprite->layer);
if (undo_is_enabled(sprite->undo))
undo_close(sprite->undo);
}
void LayerFromBackground(void)
{
console_printf("LayerFromBackground: not implemented\n");
}
/* internal routine */
static int count_layers(Layer *layer)
static int get_max_layer_num(Layer *layer)
{
int count;
int max = 0;
if (layer->parent_layer == NULL)
count = 0;
else
count = 1;
if (strncmp(layer->name, "Layer ", 6) == 0)
max = strtol(layer->name+6, NULL, 10);
if (layer_is_set(layer)) {
JLink link;
JI_LIST_FOR_EACH(layer->layers, link) {
count += count_layers(link->data);
}
}
return count;
}
/* internal routine */
static void undo_remove_stock_images(Layer *layer)
{
JLink link;
if (layer_is_set(layer)) {
JI_LIST_FOR_EACH(layer->layers, link)
undo_remove_stock_images(link->data);
}
else if (layer_is_image(layer)) {
JI_LIST_FOR_EACH(layer->cels, link) {
Cel *cel = link->data;
if (!cel_is_link(cel, layer))
undo_remove_image(layer->sprite->undo,
layer->sprite->stock,
stock_get_image(layer->sprite->stock,
cel->image));
int tmp = get_max_layer_num(link->data);
max = MAX(tmp, max);
}
}
return max;
}
/* ======================================= */
@ -474,3 +811,36 @@ void RemoveCel(Layer *layer, Cel *cel)
cel_free(cel);
}
}
void CropCel(void)
{
Sprite *sprite = current_sprite;
Image *image = GetImage(current_sprite);
if ((sprite) && (!mask_is_empty (sprite->mask)) && (image)) {
Cel *cel = layer_get_cel(sprite->layer, sprite->frame);
/* undo */
undo_open(sprite->undo);
undo_int(sprite->undo, (GfxObj *)cel, &cel->x);
undo_int(sprite->undo, (GfxObj *)cel, &cel->y);
undo_replace_image(sprite->undo, sprite->stock, cel->image);
undo_close(sprite->undo);
/* replace the image */
sprite->stock->image[cel->image] =
image_crop(image,
sprite->mask->x-cel->x,
sprite->mask->y-cel->y,
sprite->mask->w,
sprite->mask->h);
image_free(image); /* destroy the old image */
/* change the cel position */
cel->x = sprite->mask->x;
cel->y = sprite->mask->y;
update_screen_for_sprite(sprite);
}
}

View File

@ -33,6 +33,8 @@ void SaveSprite(const char *filename);
void SetSprite(struct Sprite *sprite);
void CropSprite(void);
/*===================================================================*/
/* Layer */
/*===================================================================*/
@ -45,10 +47,17 @@ char *GetUniqueLayerName(void);
struct Layer *FlattenLayers(void);
void CropLayer(void);
void BackgroundFromLayer(void);
void LayerFromBackground(void);
/* ======================================= */
/* Cel */
/* ======================================= */
void RemoveCel(struct Layer *layer, struct Cel *cel);
void CropCel(void);
#endif /* SCRIPT_FUNCTIONS_H */

View File

@ -85,7 +85,7 @@ int main (int argc, char *argv[])
redraw = TRUE;
}
dirty_get(dirty);
dirty_save_image_data(dirty);
algo_dirty(dirty, image, (AlgoHLine)draw_dirty);
ox = mx;
@ -95,7 +95,7 @@ int main (int argc, char *argv[])
/* with R restore the image */
if (key[KEY_R]) {
dirty_put(dirty);
dirty_restore_image_data(dirty);
dirty_free(dirty);
dirty = dirty_new(image, 0, 0, image->w-1, image->h-1, FALSE);
while (key[KEY_R]);

View File

@ -22,8 +22,8 @@
#include "raster/image.h"
#include "raster/mask.h"
#include "raster/sprite.h"
#include "script/functions.h"
#include "util/autocrop.h"
#include "util/crop.h"
void autocrop_sprite(void)
{
@ -70,7 +70,7 @@ void autocrop_sprite(void)
mask_replace(mask, x1, y1, x2-x1+1, y2-y1+1);
sprite->mask = mask;
crop_sprite();
CropSprite();
sprite->mask = old_mask;
sprite_generate_mask_boundaries(sprite);

View File

@ -132,13 +132,14 @@ void copy_image_to_clipboard(Image *image)
void cut_to_clipboard(void)
{
if (!current_sprite)
if (current_sprite == NULL ||
current_sprite->layer == NULL)
return;
if (!low_copy())
console_printf("Can't copying an image portion from the current layer\n");
else {
ClearMask(color_mask());
ClearMask();
update_screen_for_sprite(current_sprite);
}
}
@ -353,7 +354,7 @@ static bool interactive_transform(JWidget widget,
x1, y1, x2, y2, angle, cx, cy);
if (in_box) {
jmouse_set_cursor(JI_CURSOR_MOVE);
jmouse_set_cursor(JI_CURSOR_SCROLL);
action = ACTION_MOVE;
}
else {

View File

@ -1,224 +0,0 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2008 David A. Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "jinete/jlist.h"
#include "console/console.h"
#include "modules/gui.h"
#include "modules/sprites.h"
#include "raster/cel.h"
#include "raster/image.h"
#include "raster/layer.h"
#include "raster/mask.h"
#include "raster/sprite.h"
#include "raster/stock.h"
#include "raster/undo.h"
#include "util/misc.h"
static void displace_layers(Undo *undo, Layer *layer, int x, int y);
void crop_sprite(void)
{
Sprite *sprite = current_sprite;
if ((sprite) && (!mask_is_empty (sprite->mask))) {
if (undo_is_enabled (sprite->undo)) {
undo_open (sprite->undo);
undo_int (sprite->undo, (GfxObj *)sprite, &sprite->w);
undo_int (sprite->undo, (GfxObj *)sprite, &sprite->h);
}
sprite_set_size(sprite, sprite->mask->w, sprite->mask->h);
displace_layers(sprite->undo, sprite->set,
-sprite->mask->x, -sprite->mask->y);
if (undo_is_enabled(sprite->undo)) {
undo_int(sprite->undo, (GfxObj *)sprite->mask, &sprite->mask->x);
undo_int(sprite->undo, (GfxObj *)sprite->mask, &sprite->mask->y);
}
sprite->mask->x = 0;
sprite->mask->y = 0;
if (undo_is_enabled(sprite->undo))
undo_close(sprite->undo);
sprite_generate_mask_boundaries(sprite);
update_screen_for_sprite(sprite);
}
}
void crop_layer(void)
{
Sprite *sprite = current_sprite;
if ((sprite) && (!mask_is_empty(sprite->mask)) &&
(sprite->layer) && (layer_is_image(sprite->layer))) {
Layer *layer = sprite->layer;
Cel *cel;
Image *image;
Layer *new_layer;
Cel *new_cel;
Image *new_image;
Layer *set = layer->parent_layer;
JLink link;
new_layer = layer_new(sprite);
if (!new_layer) {
console_printf(_("Not enough memory\n"));
return;
}
layer_set_name(new_layer, layer->name);
layer_set_blend_mode(new_layer, layer->blend_mode);
JI_LIST_FOR_EACH(layer->cels, link) {
cel = link->data;
image = stock_get_image(sprite->stock, cel->image);
if (!image)
continue;
new_cel = cel_new_copy(cel);
if (!new_cel) {
layer_free(new_layer);
console_printf(_("Not enough memory\n"));
return;
}
new_image = image_crop(image,
sprite->mask->x-cel->x,
sprite->mask->y-cel->y,
sprite->mask->w,
sprite->mask->h);
if (!new_image) {
layer_free(new_layer);
cel_free(new_cel);
console_printf(_("Not enough memory\n"));
return;
}
new_cel->image = stock_add_image(sprite->stock, new_image);
new_cel->x = sprite->mask->x;
new_cel->y = sprite->mask->y;
layer_add_cel(new_layer, new_cel);
}
/* add the new layer */
if (undo_is_enabled(sprite->undo)) {
undo_open(sprite->undo);
undo_add_layer(sprite->undo, set, new_layer);
}
layer_add_layer(set, new_layer);
/* move it after the old one */
if (undo_is_enabled(sprite->undo))
undo_move_layer(sprite->undo, new_layer);
layer_move_layer(set, new_layer, layer);
/* set the new one as the current one */
if (undo_is_enabled(sprite->undo))
undo_set_layer(sprite->undo, sprite);
sprite_set_layer(sprite, new_layer);
/* remove the old layer */
if (undo_is_enabled(sprite->undo)) {
undo_remove_layer(sprite->undo, layer);
undo_close(sprite->undo);
}
layer_remove_layer(set, layer);
layer_free(layer);
/* refresh */
update_screen_for_sprite(sprite);
}
}
void crop_cel(void)
{
Sprite *sprite = current_sprite;
Image *image = GetImage(current_sprite);
if ((sprite) && (!mask_is_empty (sprite->mask)) && (image)) {
Cel *cel = layer_get_cel(sprite->layer, sprite->frame);
/* undo */
undo_open(sprite->undo);
undo_int(sprite->undo, (GfxObj *)cel, &cel->x);
undo_int(sprite->undo, (GfxObj *)cel, &cel->y);
undo_replace_image(sprite->undo, sprite->stock, cel->image);
undo_close(sprite->undo);
/* replace the image */
sprite->stock->image[cel->image] =
image_crop(image,
sprite->mask->x-cel->x,
sprite->mask->y-cel->y,
sprite->mask->w,
sprite->mask->h);
image_free(image); /* destroy the old image */
/* change the cel position */
cel->x = sprite->mask->x;
cel->y = sprite->mask->y;
update_screen_for_sprite(sprite);
}
}
/* Moves every frame in "layer" with the offset "x"/"y". */
static void displace_layers(Undo *undo, Layer *layer, int x, int y)
{
switch (layer->gfxobj.type) {
case GFXOBJ_LAYER_IMAGE: {
Cel *cel;
JLink link;
JI_LIST_FOR_EACH(layer->cels, link) {
cel = link->data;
if (undo_is_enabled(undo)) {
undo_int(undo, (GfxObj *)cel, &cel->x);
undo_int(undo, (GfxObj *)cel, &cel->y);
}
cel->x += x;
cel->y += y;
}
break;
}
case GFXOBJ_LAYER_SET: {
JLink link;
JI_LIST_FOR_EACH(layer->layers, link)
displace_layers(undo, link->data, x, y);
break;
}
}
}

View File

@ -61,7 +61,9 @@ Image *GetImage2(Sprite *sprite, int *x, int *y, int *opacity)
{
Image *image = NULL;
if (sprite && sprite->layer && layer_is_image(sprite->layer)) {
if (sprite != NULL &&
sprite->layer != NULL &&
layer_is_image(sprite->layer)) {
Cel *cel = layer_get_cel(sprite->layer, sprite->frame);
if (cel) {
@ -113,26 +115,25 @@ void LoadPalette(const char *filename)
}
/* clears the mask region in the current sprite with the BG color */
void ClearMask(color_t _color)
void ClearMask(void)
{
Sprite *sprite = current_sprite;
int x, y, u, v, putx, puty;
ase_uint8 *address;
Image *image;
div_t d;
int color;
if (sprite) {
image = GetImage2(sprite, &x, &y, NULL);
if (image) {
color = get_color_for_image(sprite->imgtype, _color);
int bgcolor = app_get_color_to_clear_layer(sprite->layer);
if (mask_is_empty(sprite->mask)) {
if (undo_is_enabled(sprite->undo))
undo_image(sprite->undo, image, 0, 0, image->w, image->h);
/* clear all */
image_clear(image, color);
image_clear(image, bgcolor);
}
else {
int x1 = MAX(0, sprite->mask->x);
@ -156,7 +157,7 @@ void ClearMask(color_t _color)
if ((*address & (1<<d.rem))) {
putx = u+sprite->mask->x-x;
puty = v+sprite->mask->y-y;
image_putpixel(image, putx, puty, color);
image_putpixel(image, putx, puty, bgcolor);
}
_image_bitmap_next_bit(d, address);

View File

@ -33,7 +33,7 @@ struct Image *GetImage2(struct Sprite *sprite, int *x, int *y, int *opacity);
void LoadPalette(const char *filename);
void ClearMask(color_t color);
void ClearMask(void);
struct Layer *NewLayerFromMask(struct Sprite *src, struct Sprite *dst);
struct Image *GetLayerImage(struct Layer *layer, int *x, int *y, int frame);

View File

@ -45,7 +45,7 @@ static void merge_zoomed_image1(Image *dst, Image *src, int x, int y, int opacit
static void merge_zoomed_image2(Image *dst, Image *src, int x, int y, int opacity, int blend_mode, int zoom);
static void merge_zoomed_image4(Image *dst, Image *src, int x, int y, int opacity, int blend_mode, int zoom);
void set_preview_image (Layer *layer, Image *image)
void set_preview_image(Layer *layer, Image *image)
{
selected_layer = layer;
rastering_image = image;
@ -64,26 +64,24 @@ Image *render_sprite(Sprite *sprite,
int frame, int zoom)
{
void (*zoomed_func)(Image *, Image *, int, int, int, int, int);
int need_grid, depth;
bool need_grid = sprite_need_alpha(sprite);
int depth;
Image *image;
switch (sprite->imgtype) {
case IMAGE_RGB:
depth = 32;
need_grid = _rgba_geta(sprite->bgcolor) < 255;
zoomed_func = merge_zoomed_image4;
break;
case IMAGE_GRAYSCALE:
depth = 8;
need_grid = _graya_geta(sprite->bgcolor) < 255;
zoomed_func = merge_zoomed_image2;
break;
case IMAGE_INDEXED:
depth = 8;
need_grid = FALSE;
zoomed_func = merge_zoomed_image1;
break;
@ -107,12 +105,12 @@ Image *render_sprite(Sprite *sprite,
switch (image->imgtype) {
case IMAGE_RGB:
c1 = _rgba_blend_normal(_rgba(128, 128, 128, 255), sprite->bgcolor, 255);
c2 = _rgba_blend_normal(_rgba(192, 192, 192, 255), sprite->bgcolor, 255);
c1 = _rgba(128, 128, 128, 255); /* TODO configurable grid color */
c2 = _rgba(192, 192, 192, 255);
break;
case IMAGE_GRAYSCALE:
c1 = _graya_blend_normal(_graya(128, 255), sprite->bgcolor, 255);
c2 = _graya_blend_normal(_graya(192, 255), sprite->bgcolor, 255);
c1 = _graya(128, 255);
c2 = _graya(192, 255);
break;
/* case IMAGE_INDEXED: */
/* c1 = rgb_map->data[16][16][16]; */
@ -152,7 +150,7 @@ Image *render_sprite(Sprite *sprite,
#endif
}
else
image_clear(image, sprite->bgcolor);
image_clear(image, 0);
color_map = NULL;
@ -181,7 +179,7 @@ static void render_layer(Layer *layer, Image *image,
void (*zoomed_func)(Image *, Image *, int, int, int, int, int))
{
/* we can't read from this layer */
if (!layer->readable)
if (!layer_is_readable(layer))
return;
/* /\* onion-skin feature *\/ */

View File

@ -45,10 +45,9 @@
#define COLORBAR_MAX_COLORS 256
typedef enum {
HOTCOLOR_NONE = -4,
HOTCOLOR_FGCOLOR = -3,
HOTCOLOR_BGCOLOR = -2,
HOTCOLOR_BGSPRITE = -1,
HOTCOLOR_NONE = -3,
HOTCOLOR_FGCOLOR = -2,
HOTCOLOR_BGCOLOR = -1,
HOTCOLOR_GRADIENT = 0,
} hotcolor_t;
@ -69,7 +68,7 @@ static ColorBar *colorbar_data(JWidget colorbar);
static bool colorbar_msg_proc(JWidget widget, JMessage msg);
static color_t colorbar_get_hot_color(JWidget widget);
static void colorbar_open_tooltip(JWidget widget, int x, int y1, int y2,
static void colorbar_open_tooltip(JWidget widget, int x1, int x2, int y1, int y2,
color_t color, hotcolor_t hot);
static void colorbar_close_tooltip(JWidget widget);
@ -182,7 +181,7 @@ color_t colorbar_get_color_by_position(JWidget widget, int x, int y)
++x1, ++y1, --x2, --y2;
h = (y2-y1+1-(4+16+4+16+16+4));
h = (y2-y1+1-(4+16+16+4));
for (c=beg; c<=end; c++) {
v1 = y1 + h*(c-beg )/(end-beg+1);
@ -192,29 +191,18 @@ color_t colorbar_get_color_by_position(JWidget widget, int x, int y)
return colorbar->color[c];
}
/* in tool foreground color */
v1 = y2-4-16-4-16-16;
v2 = y2-4-16-4-16;
/* in foreground color */
v1 = y2-4-16-16;
v2 = y2-4-16;
if ((y >= v1) && (y <= v2)) {
return colorbar->fgcolor;
}
/* in tool background color */
v1 = y2-4-16-4-16+1;
v2 = y2-4-16-4;
if ((y >= v1) && (y <= v2)) {
return colorbar->bgcolor;
}
/* in sprite background color */
v1 = y2-4-16;
/* in background color */
v1 = y2-4-16+1;
v2 = y2-4;
if ((y >= v1) && (y <= v2)) {
color_t c =
current_sprite != NULL ? color_from_image(current_sprite->imgtype,
current_sprite->bgcolor):
color_mask();
return c;
return colorbar->bgcolor;
}
return color_mask();
@ -296,7 +284,7 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
rectfill(doublebuffer, x1, y1, x2, y2, ji_color_face());
++x1, ++y1, --x2, --y2;
h = (y2-y1+1-(4+16+4+16+16+4));
h = (y2-y1+1-(4+16+16+4));
/* draw gradient */
for (c=beg; c<=end; c++) {
@ -310,36 +298,22 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
c == colorbar->hot_editing));
}
/* draw tool foreground color */
v1 = y2-4-16-4-16-16;
v2 = y2-4-16-4-16;
/* draw foreground color */
v1 = y2-4-16-16;
v2 = y2-4-16;
draw_color_button(doublebuffer, x1, v1, x2, v2, 1, 1, 0, 0,
imgtype, colorbar->fgcolor,
(colorbar->hot == HOTCOLOR_FGCOLOR ||
colorbar->hot_editing == HOTCOLOR_FGCOLOR));
/* draw tool background color */
v1 = y2-4-16-4-16+1;
v2 = y2-4-16-4;
/* draw background color */
v1 = y2-4-16+1;
v2 = y2-4;
draw_color_button(doublebuffer, x1, v1, x2, v2, 0, 0, 1, 1,
imgtype, colorbar->bgcolor,
(colorbar->hot == HOTCOLOR_BGCOLOR ||
colorbar->hot_editing == HOTCOLOR_BGCOLOR));
/* draw sprite background color */
v1 = y2-4-16;
v2 = y2-4;
{
color_t c =
current_sprite != NULL ? color_from_image(imgtype,
current_sprite->bgcolor):
color_mask();
draw_color_button(doublebuffer, x1, v1, x2, v2, 1, 1, 1, 1,
imgtype, c,
(colorbar->hot == HOTCOLOR_BGSPRITE ||
colorbar->hot_editing == HOTCOLOR_BGSPRITE));
}
blit(doublebuffer, ji_screen, 0, 0,
msg->draw.rect.x1,
msg->draw.rect.y1,
@ -371,7 +345,7 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
++x1, ++y1, --x2, --y2;
h = (y2-y1+1-(4+16+4+16+16+4));
h = (y2-y1+1-(4+16+16+4));
for (c=beg; c<=end; c++) {
v1 = y1 + h*(c-beg )/(end-beg+1);
@ -387,29 +361,20 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
}
}
/* in tool foreground color */
v1 = y2-4-16-4-16-16;
v2 = y2-4-16-4-16;
/* in foreground color */
v1 = y2-4-16-16;
v2 = y2-4-16;
if ((msg->mouse.y >= v1) && (msg->mouse.y <= v2)) {
colorbar->hot = HOTCOLOR_FGCOLOR;
hot_v1 = v1;
hot_v2 = v2;
}
/* in tool background color */
v1 = y2-4-16-4-16+1;
v2 = y2-4-16-4;
if ((msg->mouse.y >= v1) && (msg->mouse.y <= v2)) {
colorbar->hot = HOTCOLOR_BGCOLOR;
hot_v1 = v1;
hot_v2 = v2;
}
/* in sprite background color */
v1 = y2-4-16;
/* in background color */
v1 = y2-4-16+1;
v2 = y2-4;
if ((msg->mouse.y >= v1) && (msg->mouse.y <= v2)) {
colorbar->hot = HOTCOLOR_BGSPRITE;
colorbar->hot = HOTCOLOR_BGCOLOR;
hot_v1 = v1;
hot_v2 = v2;
}
@ -427,7 +392,7 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
update_status_bar(color, 0);
/* open the tooltip window to edit the hot color */
colorbar_open_tooltip(widget, widget->rc->x2+1,
colorbar_open_tooltip(widget, widget->rc->x1-1, widget->rc->x2+1,
hot_v1, hot_v2, color, colorbar->hot);
}
}
@ -495,13 +460,6 @@ static color_t colorbar_get_hot_color(JWidget widget)
case HOTCOLOR_NONE: return color_mask();
case HOTCOLOR_FGCOLOR: return colorbar->fgcolor;
case HOTCOLOR_BGCOLOR: return colorbar->bgcolor;
case HOTCOLOR_BGSPRITE: {
int imgtype = app_get_current_image_type();
return
current_sprite != NULL ? color_from_image(imgtype,
current_sprite->bgcolor):
color_mask();
}
default:
assert(colorbar->hot >= 0 &&
colorbar->hot < colorbar->ncolor);
@ -509,13 +467,13 @@ static color_t colorbar_get_hot_color(JWidget widget)
}
}
static void colorbar_open_tooltip(JWidget widget, int x, int y1, int y2,
static void colorbar_open_tooltip(JWidget widget, int x1, int x2, int y1, int y2,
color_t color, hotcolor_t hot)
{
ColorBar *colorbar = colorbar_data(widget);
JWidget window;
char buf[1024]; /* TODO warning buffer overflow */
int y;
int x, y;
if (colorbar->tooltip_window == NULL) {
window = colorselector_new(TRUE);
@ -535,7 +493,7 @@ static void colorbar_open_tooltip(JWidget widget, int x, int y1, int y2,
case HOTCOLOR_FGCOLOR: {
Command *cmd;
ustrcpy(buf, _("Tool Foreground Color"));
ustrcpy(buf, _("Foreground Color"));
cmd = command_get_by_name(CMD_SWITCH_COLORS);
assert(cmd != NULL);
@ -548,10 +506,7 @@ static void colorbar_open_tooltip(JWidget widget, int x, int y1, int y2,
break;
}
case HOTCOLOR_BGCOLOR:
ustrcpy(buf, _("Tool Background Color"));
break;
case HOTCOLOR_BGSPRITE:
ustrcpy(buf, _("Sprite Background Color"));
ustrcpy(buf, _("Background Color"));
break;
default:
usprintf(buf, _("Gradient Entry %d"), colorbar->hot);
@ -564,9 +519,16 @@ static void colorbar_open_tooltip(JWidget widget, int x, int y1, int y2,
jwindow_open(window);
x = MID(0, x, JI_SCREEN_W-jrect_w(window->rc));
/* window position */
if (x2+jrect_w(window->rc) <= JI_SCREEN_W)
x = x2;
else
x = x1-jrect_w(window->rc);
y = (y1+y2)/2-jrect_h(window->rc)/2;
x = MID(0, x, JI_SCREEN_W-jrect_w(window->rc));
y = MID(widget->rc->y1, y, widget->rc->y2-jrect_h(window->rc));
jwindow_position(window, x, y);
jmanager_dispatch_messages(jwidget_get_manager(window));
@ -574,11 +536,12 @@ static void colorbar_open_tooltip(JWidget widget, int x, int y1, int y2,
/* setup the hot-region */
{
JRect rc = jrect_new(window->rc->x1,
JRect rc = jrect_new(window->rc->x1-8,
window->rc->y1-8,
window->rc->x2+8,
window->rc->y2+8);
JRect rc2 = jrect_new(widget->rc->x1, y1, x, y2+1);
/* JRect rc2 = jrect_new(widget->rc->x1, y1, x, y2+1); */
JRect rc2 = jrect_new(x1, y1, x2, y2+1);
JRegion rgn = jregion_new(rc, 1);
JRegion rgn2 = jregion_new(rc2, 1);
@ -686,21 +649,6 @@ static bool tooltip_window_msg_proc(JWidget widget, JMessage msg)
case HOTCOLOR_BGCOLOR:
colorbar->bgcolor = color;
break;
case HOTCOLOR_BGSPRITE: {
if (current_sprite != NULL) {
Sprite *sprite = current_sprite;
int new_bgcolor = get_color_for_image(sprite->imgtype, color);
if (sprite->bgcolor != new_bgcolor) {
/* TODO add undo suppport */
/* if (undo_is_enabled(sprite->undo)) */
/* undo_int(sprite->undo, (GfxObj *)sprite, &sprite->bgcolor); */
sprite_set_bgcolor(sprite, new_bgcolor);
}
}
break;
}
default:
assert(colorbar->hot_editing >= 0 &&
colorbar->hot_editing < colorbar->ncolor);
@ -714,19 +662,16 @@ static bool tooltip_window_msg_proc(JWidget widget, JMessage msg)
int r1 = color_get_red(imgtype, c1);
int g1 = color_get_green(imgtype, c1);
int b1 = color_get_blue(imgtype, c1);
int a1 = color_get_alpha(imgtype, c1);
int r2 = color_get_red(imgtype, c2);
int g2 = color_get_green(imgtype, c2);
int b2 = color_get_blue(imgtype, c2);
int a2 = color_get_alpha(imgtype, c2);
int c, r, g, b, a;
int c, r, g, b;
for (c=1; c<colorbar->ncolor-1; ++c) {
r = r1 + (r2-r1) * c / colorbar->ncolor;
g = g1 + (g2-g1) * c / colorbar->ncolor;
b = b1 + (b2-b1) * c / colorbar->ncolor;
a = a1 + (a2-a1) * c / colorbar->ncolor;
colorbar->color[c] = color_rgb(r, g, b, a);
colorbar->color[c] = color_rgb(r, g, b);
}
}
break;

View File

@ -167,13 +167,17 @@ static bool colorbutton_msg_proc(JWidget widget, JMessage msg)
else if (picked->type == editor_type()) {
Sprite *sprite = editor_get_sprite(picked);
int x, y, imgcolor;
color_t tmp;
if (sprite) {
x = msg->mouse.x;
y = msg->mouse.y;
screen_to_editor(picked, x, y, &x, &y);
imgcolor = sprite_getpixel(sprite, x, y);
color = color_from_image(sprite->imgtype, imgcolor);
tmp = color_from_image(sprite->imgtype, imgcolor);
if (color_type(tmp) != COLOR_TYPE_MASK)
color = tmp;
}
}
}

View File

@ -175,29 +175,23 @@ static JWidget create_rgb_container(void)
JWidget rlabel = jlabel_new("R");
JWidget glabel = jlabel_new("G");
JWidget blabel = jlabel_new("B");
JWidget alabel = jlabel_new("A");
JWidget rslider = jslider_new(0, 255, 0);
JWidget gslider = jslider_new(0, 255, 0);
JWidget bslider = jslider_new(0, 255, 0);
JWidget aslider = jslider_new(0, 255, 0);
jgrid_add_child(grid, rlabel, 1, 1, JI_RIGHT);
jgrid_add_child(grid, rslider, 1, 1, JI_HORIZONTAL);
jgrid_add_child(grid, glabel, 1, 1, JI_RIGHT);
jgrid_add_child(grid, gslider, 1, 1, JI_HORIZONTAL);
jgrid_add_child(grid, blabel, 1, 1, JI_RIGHT);
jgrid_add_child(grid, bslider, 1, 1, JI_HORIZONTAL);
jgrid_add_child(grid, alabel, 1, 1, JI_RIGHT);
jgrid_add_child(grid, aslider, 1, 1, JI_HORIZONTAL);
jwidget_set_name(rslider, "rgb_r");
jwidget_set_name(gslider, "rgb_g");
jwidget_set_name(bslider, "rgb_b");
jwidget_set_name(aslider, "rgb_a");
HOOK(rslider, JI_SIGNAL_SLIDER_CHANGE, slider_change_hook, 0);
HOOK(gslider, JI_SIGNAL_SLIDER_CHANGE, slider_change_hook, 0);
HOOK(bslider, JI_SIGNAL_SLIDER_CHANGE, slider_change_hook, 0);
HOOK(aslider, JI_SIGNAL_SLIDER_CHANGE, slider_change_hook, 0);
return grid;
}
@ -208,29 +202,23 @@ static JWidget create_hsv_container(void)
JWidget hlabel = jlabel_new("H");
JWidget slabel = jlabel_new("S");
JWidget vlabel = jlabel_new("V");
JWidget alabel = jlabel_new("A");
JWidget hslider = jslider_new(0, 255, 0);
JWidget sslider = jslider_new(0, 255, 0);
JWidget vslider = jslider_new(0, 255, 0);
JWidget aslider = jslider_new(0, 255, 0);
jgrid_add_child(grid, hlabel, 1, 1, JI_RIGHT);
jgrid_add_child(grid, hslider, 1, 1, JI_HORIZONTAL);
jgrid_add_child(grid, slabel, 1, 1, JI_RIGHT);
jgrid_add_child(grid, sslider, 1, 1, JI_HORIZONTAL);
jgrid_add_child(grid, vlabel, 1, 1, JI_RIGHT);
jgrid_add_child(grid, vslider, 1, 1, JI_HORIZONTAL);
jgrid_add_child(grid, alabel, 1, 1, JI_RIGHT);
jgrid_add_child(grid, aslider, 1, 1, JI_HORIZONTAL);
jwidget_set_name(hslider, "hsv_h");
jwidget_set_name(sslider, "hsv_s");
jwidget_set_name(vslider, "hsv_v");
jwidget_set_name(aslider, "hsv_a");
HOOK(hslider, JI_SIGNAL_SLIDER_CHANGE, slider_change_hook, 0);
HOOK(sslider, JI_SIGNAL_SLIDER_CHANGE, slider_change_hook, 0);
HOOK(vslider, JI_SIGNAL_SLIDER_CHANGE, slider_change_hook, 0);
HOOK(aslider, JI_SIGNAL_SLIDER_CHANGE, slider_change_hook, 0);
return grid;
}
@ -239,19 +227,13 @@ static JWidget create_gray_container(void)
{
JWidget grid = jgrid_new(2, FALSE);
JWidget klabel = jlabel_new("V");
JWidget alabel = jlabel_new("A");
JWidget vslider = jslider_new(0, 255, 0);
JWidget aslider = jslider_new(0, 255, 0);
jgrid_add_child(grid, klabel, 1, 1, JI_RIGHT);
jgrid_add_child(grid, vslider, 1, 1, JI_HORIZONTAL);
jgrid_add_child(grid, alabel, 1, 1, JI_RIGHT);
jgrid_add_child(grid, aslider, 1, 1, JI_HORIZONTAL);
jwidget_set_name(vslider, "gray_v");
jwidget_set_name(aslider, "gray_a");
HOOK(vslider, JI_SIGNAL_SLIDER_CHANGE, slider_change_hook, 0);
HOOK(aslider, JI_SIGNAL_SLIDER_CHANGE, slider_change_hook, 0);
return grid;
}
@ -330,13 +312,10 @@ static void colorselector_set_color2(JWidget widget, color_t color,
JWidget rgb_rslider = jwidget_find_name(widget, "rgb_r");
JWidget rgb_gslider = jwidget_find_name(widget, "rgb_g");
JWidget rgb_bslider = jwidget_find_name(widget, "rgb_b");
JWidget rgb_aslider = jwidget_find_name(widget, "rgb_a");
JWidget hsv_hslider = jwidget_find_name(widget, "hsv_h");
JWidget hsv_sslider = jwidget_find_name(widget, "hsv_s");
JWidget hsv_vslider = jwidget_find_name(widget, "hsv_v");
JWidget hsv_aslider = jwidget_find_name(widget, "hsv_a");
JWidget gray_vslider = jwidget_find_name(widget, "gray_v");
JWidget gray_aslider = jwidget_find_name(widget, "gray_a");
colorselector->color = color;
@ -344,17 +323,14 @@ static void colorselector_set_color2(JWidget widget, color_t color,
jslider_set_value(rgb_rslider, color_get_red(imgtype, color));
jslider_set_value(rgb_gslider, color_get_green(imgtype, color));
jslider_set_value(rgb_bslider, color_get_blue(imgtype, color));
jslider_set_value(rgb_aslider, color_get_alpha(imgtype, color));
}
if (exclude_this_model != models+MODEL_HSV) {
jslider_set_value(hsv_hslider, color_get_hue(imgtype, color));
jslider_set_value(hsv_sslider, color_get_saturation(imgtype, color));
jslider_set_value(hsv_vslider, color_get_value(imgtype, color));
jslider_set_value(hsv_aslider, color_get_alpha(imgtype, color));
}
if (exclude_this_model != models+MODEL_GRAY) {
jslider_set_value(gray_vslider, color_get_value(imgtype, color));
jslider_set_value(gray_aslider, color_get_alpha(imgtype, color));
}
switch (color_type(color)) {
@ -481,32 +457,26 @@ static bool slider_change_hook(JWidget widget, void *data)
JWidget rslider = jwidget_find_name(window, "rgb_r");
JWidget gslider = jwidget_find_name(window, "rgb_g");
JWidget bslider = jwidget_find_name(window, "rgb_b");
JWidget aslider = jwidget_find_name(window, "rgb_a");
int r = jslider_get_value(rslider);
int g = jslider_get_value(gslider);
int b = jslider_get_value(bslider);
int a = jslider_get_value(aslider);
color = color_rgb(r, g, b, a);
color = color_rgb(r, g, b);
break;
}
case MODEL_HSV: {
JWidget hslider = jwidget_find_name(window, "hsv_h");
JWidget sslider = jwidget_find_name(window, "hsv_s");
JWidget vslider = jwidget_find_name(window, "hsv_v");
JWidget aslider = jwidget_find_name(window, "hsv_a");
int h = jslider_get_value(hslider);
int s = jslider_get_value(sslider);
int v = jslider_get_value(vslider);
int a = jslider_get_value(aslider);
color = color_hsv(h, s, v, a);
color = color_hsv(h, s, v);
break;
}
case MODEL_GRAY: {
JWidget vslider = jwidget_find_name(window, "gray_v");
JWidget aslider = jwidget_find_name(window, "gray_a");
int v = jslider_get_value(vslider);
int a = jslider_get_value(aslider);
color = color_gray(v, a);
color = color_gray(v);
break;
}
}

View File

@ -265,12 +265,12 @@ static bool curve_editor_msg_proc(JWidget widget, JMessage msg)
/* change scroll */
if (msg->any.shifts & KB_SHIFT_FLAG) {
curve_editor->status = STATUS_SCROLLING;
jmouse_set_cursor(JI_CURSOR_MOVE);
jmouse_set_cursor(JI_CURSOR_SCROLL);
}
/* scaling */
/* else if (msg->shifts & KB_CTRL_FLAG) { */
/* curve_editor->status = STATUS_SCALING; */
/* jmouse_set_cursor(JI_CURSOR_MOVE); */
/* jmouse_set_cursor(JI_CURSOR_SCROLL); */
/* } */
/* show manual-entry dialog */
else if (msg->mouse.right) {

Some files were not shown because too many files have changed in this diff Show More