gimp/app/core/gimpdrawable-preview.c

465 lines
13 KiB
C
Raw Normal View History

/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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 <string.h>
an evil temp_hack which lets GimpContext managing the active display 2001-08-14 Michael Natterer <mitch@gimp.org> * app/gdisplay.h: an evil temp_hack which lets GimpContext managing the active display withoug including "gdisplay.h". Will go away as soon ad context properties are registered dynamically. * app/module_db.c: cleaned up the object code in preparation of moving it to core/. * app/path.c: connect to GimpImage's * app/core/gimpobject.[ch]: derive it from GObject, not from GtkObject any more (yeah :-) * app/core/*.c: #include <glib-object.h> instead of <gtk/gtk.h>, removed some remaining GtkObject-isms. (left in a few #include <gtk/gtk.h> where bigger changes are needed to get rid of the UI dependency). * app/core/core-types.h: #include <gdk-pixbuf/gdk-pixbuf.h> here temporarily. * app/core/gimp.c (gimp_create_display): unref the image after creating it's first display. * app/core/gimpbrush.[ch]: disabled the parts of the code which depend on GimpPaintTool. * app/core/gimpbrushgenerated.c * app/core/gimpbrushpipe.c: changed accordingly. * app/core/gimpcontext.[ch]: evil hack (see above) to manage the active display without including "gdisplay.h" * app/core/gimpimage-mask.[ch]: pass a context to gimage_mask_stroke() and get the current tool's PDB string from there. * app/core/gimpedit.c: changed accordingly. * app/core/gimpimage.c: use gimp_image_update() instead of gdisplays_update_full(). * app/gui/color-area.c * app/gui/colormap-dialog.c * app/gui/dialogs-constructors.c * app/gui/edit-commands.c * app/gui/image-commands.c * app/gui/toolbox.c: changed accordingly (don't use Gtk methods on GObjects). * app/gui/menus.c: fix some const warnings by explicit casting. * app/tools/*.[ch]: ported all tools to GObject, some minor cleanup while i was on it. * app/widgets/gimpdialogfactory.[ch]: ported to GObject. * app/widgets/gimplayerlistview.h: added FOO_GET_CLASS() macro. * tools/pdbgen/app.pl: added a "widgets_eek" hack like "tools_eek" which inserts #include "widgets/widgets-types.h" before ordinary includes. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/edit.pdb * app/pdb/brush_select_cmds.c * app/pdb/edit_cmds.c: changed according to the stuff above.
2001-08-14 22:53:55 +08:00
#include <glib-object.h>
#include "libgimpmath/gimpmath.h"
#include "core-types.h"
new directory app/base/ 2001-05-15 Michael Natterer <mitch@gimp.org> * configure.in: new directory app/base/ * app/Makefile.am * app/boundary.[ch] * app/brush_scale.[ch] * app/gimpchecks.h * app/gimplut.[ch] * app/pixel_processor.[ch] * app/pixel_region.[ch] * app/pixel_surround.[ch] * app/temp_buf.[ch] * app/tile.[ch] * app/tile_cache.[ch] * app/tile_manager.[ch] * app/tile_manager_pvt.h * app/tile_pvt.h * app/tile_swap.[ch]: moved to base/ * app/base/Makefile.am * app/base/base-types.h * app/base/*: new directory for the sub-object pixel maniplation and storage stuff. Does not include Gtk+ or anything outside base/. Did some cleanup in all files. * app/appenums.h * app/apptypes.h * app/core/gimpimage.h: removed types which are now in base/base-types.h. * app/base/base-config.[ch] * app/gimprc.[ch]: put the config variables for base/ to their own file so base/ doesn not have to include gimprc.h (does not yet work, i.e. the variables are un-configurable right now) * app/main.c: set a log handler for "Gimp-Base". * app/paint-funcs/Makefile.am * app/paint-funcs/paint-funcs.[ch]: removed the color hash which maps RGB to color indices because it's a totally standalone system which has nothing to do with the paint-funcs and introduced a GimpImage dependency. paint-funcs/ should be considered on the same sub-object (glib-only) level as base/, only in a different directory. * app/core/Makefile.am * app/core/gimpimage-colorhash.[ch]: put the color hash here. * app/gimage.c: don't invalidate the color hash here... * app/core/gimpimage.c: ... but in the colormap_changed() default inplementation. Initialize the hash in class_init(). * tools/pdbgen/Makefile.am: scan app/base/base-types.h for enums. * tools/pdbgen/enums.pl: regenerated. * app/[lots] * app/core/[of] * app/gui/[files] * app/pdb/[all] * app/tools/[over] * app/widgets/[the] * tools/pdbgen/pdb/[place]: changed #includes accordingly. And use base_config->value instead of the stuff from gimprc.h.
2001-05-15 19:25:25 +08:00
#include "base/pixel-region.h"
#include "base/temp-buf.h"
#include "paint-funcs/paint-funcs.h"
themes/Default/images/stock-delete-16.png 2003-03-06 Michael Natterer <mitch@gimp.org> * themes/Default/images/stock-delete-16.png * themes/Default/images/stock-lower-16.png * themes/Default/images/stock-new-16.png * themes/Default/images/stock-paste-16.png * themes/Default/images/stock-raise-16.png * themes/Default/images/stock-refresh-16.png: removed these files since we use the icons provided by GTK+ now. * themes/Default/gtkrc * themes/Default/images/Makefile.am: removed them here hoo. * libgimpwidgets/gimpstock.[ch]: reordered stuff to be consistent in the header and the .c file. Added GIMP_STOCK_ERROR and GIMP_STOCK_QUESTION which are available in all sizes (unlike GTK_STOCK_DIALOG_ERROR and GTK_STOCK_DIALOG_QUESTION). * app/core/gimpviewable.c * app/display/gimpdisplayshell.c * app/gui/file-commands.c * app/gui/file-new-dialog.c * app/gui/file-save-dialog.c * app/widgets/gimpwidgets-utils.c * app/widgets/gimpdatafactoryview.c: use the new stock IDs. * app/config/gimpcoreconfig.[ch]: renamed "preview_size" to "layer_preview_size" and added "gboolean layer_previews" which switches layer previews on/off independent of their size. * app/config/gimprc-blurbs.h: added/changed their blurbs. * app/core/core-enums.[ch]: removed GIMP_PREVIEW_SIZE_NONE. * app/core/gimpdrawable-preview.c * app/core/gimpdrawable.c * app/core/gimpimage.c: return NULL previews if core_config->layer_previews is FALSE. Invalidate all layer/channel previews whenever "layer_previews" changes. * app/widgets/gimppreviewrendererdrawable.c * app/widgets/gimppreviewrendererimage.c: render the stock_id if the drawable/image returns a NULL preview. Fixes bug #107242. * app/display/gimpdisplayshell-handlers.c: don't set the sensitivity of the navigation button because it can no longer be disabled. * app/display/gimpdisplayshell-layer-select.c * app/gui/dialogs-constructors.c * app/gui/dialogs.c * app/gui/paths-dialog.c: changed accordingly. * app/gui/preferences-dialog.c: added a toggle button for the new "layer_previews" boolean. * app/widgets/gimpcontainergridview.c * app/widgets/gimpcontainerlistview.c: chain up unconditionally in GimpContainerView::clear_items(). * app/widgets/gimpcontainertreeview.c: ditto. Made the reorder() implementation lengthy and eeky (but working) again... Stop signal emission on double clicks so GtkTreeView doesn't re-select the item we are about change. * app/widgets/gimpcontainerview.c (gimp_container_view_real_clear_items): need to use g_hash_table_new_full() here too or everything will b0rk. * app/widgets/gimppreviewrenderer.c (gimp_preview_renderer_default_render_stock): use gtk_widget_render_icon() instead of gtk_icon_set_render_icon(). * tools/pdbgen/enums.pl: this file wanted to be regenerated...
2003-03-07 00:47:34 +08:00
#include "config/gimpcoreconfig.h"
#include "gimp.h"
#include "gimpchannel.h"
#include "gimpimage.h"
2003-09-06 01:44:39 +08:00
#include "gimpimage-colormap.h"
#include "gimpdrawable-preview.h"
#include "gimplayer.h"
#include "gimppreviewcache.h"
/* local function prototypes */
static TempBuf * gimp_drawable_preview_private (GimpDrawable *drawable,
gint width,
gint height);
static void gimp_drawable_preview_scale (GimpImageType type,
const guchar *cmap,
PixelRegion *srcPR,
PixelRegion *destPR,
gint subsample);
/* public functions */
TempBuf *
gimp_drawable_get_preview (GimpViewable *viewable,
gint width,
gint height)
{
GimpDrawable *drawable;
app/core/Makefile.am app/core/core-types.h new base class for something 2002-02-25 Michael Natterer <mitch@gimp.org> * app/core/Makefile.am * app/core/core-types.h * app/core/gimpitem.[ch]: new base class for something which is a child of an image, has a PDB ID, a tattoo, parasites and emits a "removed" signal. * app/core/gimpdrawable.[ch] * app/vectors/gimpvectors.[ch]: derive from GimpItem. Removed lots of stuff from GimpDrawable. * app/core/gimp.[ch]: changed gimp->drawable_table and gimp->next_drawable_ID to gimp->item_table and gimp->next_item_id. * app/undo.[ch]: s/undo_push_drawable_parasite/undo_push_item_parasite/, minor cleanups. * app/core/gimplayer.[ch]: changed gimp_layer_new_from_tiles() and gimp_layer_new_from_drawable() to take the "dest_gimage" as second, not first parameter. * app/image_map.c * app/core/gimpchannel.c * app/core/gimpdrawable-blend.c * app/core/gimpdrawable-bucket-fill.c * app/core/gimpdrawable-histogram.c * app/core/gimpdrawable-offset.c * app/core/gimpdrawable-preview.c * app/core/gimpdrawable-transform.c * app/core/gimpedit.c * app/core/gimpimage-duplicate.c * app/core/gimpimage-mask.c * app/core/gimpimage-merge.c * app/core/gimpimage-pick-color.c * app/core/gimpimage.c * app/core/gimplayer-floating-sel.c * app/display/gimpdisplayshell-dnd.c * app/file/file-save.c * app/gui/channels-commands.c * app/gui/file-save-dialog.c * app/gui/layers-commands.c * app/gui/offset-dialog.c * app/gui/paths-dialog.c * app/gui/toolbox.c * app/paint/gimpairbrush.c * app/paint/gimpclone.c * app/paint/gimpconvolve.c * app/paint/gimpdodgeburn.c * app/paint/gimperaser.c * app/paint/gimppaintbrush.c * app/paint/gimppaintcore.c * app/paint/gimppencil.c * app/paint/gimpsmudge.c * app/plug-in/plug-in.c * app/tools/gimpbezierselecttool.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpinktool.c * app/tools/gimppainttool.c * app/xcf/xcf-load.c * app/xcf/xcf-save.c * app/widgets/gimpdrawablepreview.c: changed accordingly. * app/widgets/Makefile.am * app/widgets/widgets-types.h * app/widgets/gimpitemlistview.[ch]: new widget implementing most of the stuff formerly done by GimpDrawableListView. * app/widgets/gimpchannellistview.c * app/widgets/gimpdrawablelistitem.c * app/widgets/gimpdrawablelistview.[ch] * app/widgets/gimplayerlistview.c: changed accordingly. * app/widgets/gimpdnd.[ch]: added a vectors DND type. * app/gui/menus.c * app/gui/dialogs.c * app/gui/dialogs-constructors.[ch]: added a vectors dialog and a vectors item_factory. * app/gui/Makefile.am * app/gui/vectors-commands.[ch]: new files implementing the callbacks for the new vectors dialog and item_factory. * app/pdb/pdb_glue.h: some more ugly hacks to keep intermediate perl code working... * tools/pdbgen/pdb.pl: added a vectors type, use GimpItem for all ID lookups. * tools/pdbgen/pdb/channel.pdb * tools/pdbgen/pdb/color.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/edit.pdb * tools/pdbgen/pdb/image.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/misc_tools.pdb * tools/pdbgen/pdb/parasite.pdb * tools/pdbgen/pdb/selection.pdb * tools/pdbgen/pdb/selection_tools.pdb: misc changes according to stuff above. * app/pdb/channel_cmds.c * app/pdb/color_cmds.c * app/pdb/drawable_cmds.c * app/pdb/edit_cmds.c * app/pdb/floating_sel_cmds.c * app/pdb/image_cmds.c * app/pdb/layer_cmds.c * app/pdb/misc_tools_cmds.c * app/pdb/paint_tools_cmds.c * app/pdb/parasite_cmds.c * app/pdb/selection_cmds.c * app/pdb/selection_tools_cmds.c * app/pdb/text_tool_cmds.c * app/pdb/transform_tools_cmds.c: regenerated.
2002-02-26 01:58:50 +08:00
GimpImage *gimage;
drawable = GIMP_DRAWABLE (viewable);
gimage = gimp_item_get_image (GIMP_ITEM (drawable));
app/core/Makefile.am app/core/core-types.h new base class for something 2002-02-25 Michael Natterer <mitch@gimp.org> * app/core/Makefile.am * app/core/core-types.h * app/core/gimpitem.[ch]: new base class for something which is a child of an image, has a PDB ID, a tattoo, parasites and emits a "removed" signal. * app/core/gimpdrawable.[ch] * app/vectors/gimpvectors.[ch]: derive from GimpItem. Removed lots of stuff from GimpDrawable. * app/core/gimp.[ch]: changed gimp->drawable_table and gimp->next_drawable_ID to gimp->item_table and gimp->next_item_id. * app/undo.[ch]: s/undo_push_drawable_parasite/undo_push_item_parasite/, minor cleanups. * app/core/gimplayer.[ch]: changed gimp_layer_new_from_tiles() and gimp_layer_new_from_drawable() to take the "dest_gimage" as second, not first parameter. * app/image_map.c * app/core/gimpchannel.c * app/core/gimpdrawable-blend.c * app/core/gimpdrawable-bucket-fill.c * app/core/gimpdrawable-histogram.c * app/core/gimpdrawable-offset.c * app/core/gimpdrawable-preview.c * app/core/gimpdrawable-transform.c * app/core/gimpedit.c * app/core/gimpimage-duplicate.c * app/core/gimpimage-mask.c * app/core/gimpimage-merge.c * app/core/gimpimage-pick-color.c * app/core/gimpimage.c * app/core/gimplayer-floating-sel.c * app/display/gimpdisplayshell-dnd.c * app/file/file-save.c * app/gui/channels-commands.c * app/gui/file-save-dialog.c * app/gui/layers-commands.c * app/gui/offset-dialog.c * app/gui/paths-dialog.c * app/gui/toolbox.c * app/paint/gimpairbrush.c * app/paint/gimpclone.c * app/paint/gimpconvolve.c * app/paint/gimpdodgeburn.c * app/paint/gimperaser.c * app/paint/gimppaintbrush.c * app/paint/gimppaintcore.c * app/paint/gimppencil.c * app/paint/gimpsmudge.c * app/plug-in/plug-in.c * app/tools/gimpbezierselecttool.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpinktool.c * app/tools/gimppainttool.c * app/xcf/xcf-load.c * app/xcf/xcf-save.c * app/widgets/gimpdrawablepreview.c: changed accordingly. * app/widgets/Makefile.am * app/widgets/widgets-types.h * app/widgets/gimpitemlistview.[ch]: new widget implementing most of the stuff formerly done by GimpDrawableListView. * app/widgets/gimpchannellistview.c * app/widgets/gimpdrawablelistitem.c * app/widgets/gimpdrawablelistview.[ch] * app/widgets/gimplayerlistview.c: changed accordingly. * app/widgets/gimpdnd.[ch]: added a vectors DND type. * app/gui/menus.c * app/gui/dialogs.c * app/gui/dialogs-constructors.[ch]: added a vectors dialog and a vectors item_factory. * app/gui/Makefile.am * app/gui/vectors-commands.[ch]: new files implementing the callbacks for the new vectors dialog and item_factory. * app/pdb/pdb_glue.h: some more ugly hacks to keep intermediate perl code working... * tools/pdbgen/pdb.pl: added a vectors type, use GimpItem for all ID lookups. * tools/pdbgen/pdb/channel.pdb * tools/pdbgen/pdb/color.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/edit.pdb * tools/pdbgen/pdb/image.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/misc_tools.pdb * tools/pdbgen/pdb/parasite.pdb * tools/pdbgen/pdb/selection.pdb * tools/pdbgen/pdb/selection_tools.pdb: misc changes according to stuff above. * app/pdb/channel_cmds.c * app/pdb/color_cmds.c * app/pdb/drawable_cmds.c * app/pdb/edit_cmds.c * app/pdb/floating_sel_cmds.c * app/pdb/image_cmds.c * app/pdb/layer_cmds.c * app/pdb/misc_tools_cmds.c * app/pdb/paint_tools_cmds.c * app/pdb/parasite_cmds.c * app/pdb/selection_cmds.c * app/pdb/selection_tools_cmds.c * app/pdb/text_tool_cmds.c * app/pdb/transform_tools_cmds.c: regenerated.
2002-02-26 01:58:50 +08:00
if (! gimage->gimp->config->layer_previews)
themes/Default/images/stock-delete-16.png 2003-03-06 Michael Natterer <mitch@gimp.org> * themes/Default/images/stock-delete-16.png * themes/Default/images/stock-lower-16.png * themes/Default/images/stock-new-16.png * themes/Default/images/stock-paste-16.png * themes/Default/images/stock-raise-16.png * themes/Default/images/stock-refresh-16.png: removed these files since we use the icons provided by GTK+ now. * themes/Default/gtkrc * themes/Default/images/Makefile.am: removed them here hoo. * libgimpwidgets/gimpstock.[ch]: reordered stuff to be consistent in the header and the .c file. Added GIMP_STOCK_ERROR and GIMP_STOCK_QUESTION which are available in all sizes (unlike GTK_STOCK_DIALOG_ERROR and GTK_STOCK_DIALOG_QUESTION). * app/core/gimpviewable.c * app/display/gimpdisplayshell.c * app/gui/file-commands.c * app/gui/file-new-dialog.c * app/gui/file-save-dialog.c * app/widgets/gimpwidgets-utils.c * app/widgets/gimpdatafactoryview.c: use the new stock IDs. * app/config/gimpcoreconfig.[ch]: renamed "preview_size" to "layer_preview_size" and added "gboolean layer_previews" which switches layer previews on/off independent of their size. * app/config/gimprc-blurbs.h: added/changed their blurbs. * app/core/core-enums.[ch]: removed GIMP_PREVIEW_SIZE_NONE. * app/core/gimpdrawable-preview.c * app/core/gimpdrawable.c * app/core/gimpimage.c: return NULL previews if core_config->layer_previews is FALSE. Invalidate all layer/channel previews whenever "layer_previews" changes. * app/widgets/gimppreviewrendererdrawable.c * app/widgets/gimppreviewrendererimage.c: render the stock_id if the drawable/image returns a NULL preview. Fixes bug #107242. * app/display/gimpdisplayshell-handlers.c: don't set the sensitivity of the navigation button because it can no longer be disabled. * app/display/gimpdisplayshell-layer-select.c * app/gui/dialogs-constructors.c * app/gui/dialogs.c * app/gui/paths-dialog.c: changed accordingly. * app/gui/preferences-dialog.c: added a toggle button for the new "layer_previews" boolean. * app/widgets/gimpcontainergridview.c * app/widgets/gimpcontainerlistview.c: chain up unconditionally in GimpContainerView::clear_items(). * app/widgets/gimpcontainertreeview.c: ditto. Made the reorder() implementation lengthy and eeky (but working) again... Stop signal emission on double clicks so GtkTreeView doesn't re-select the item we are about change. * app/widgets/gimpcontainerview.c (gimp_container_view_real_clear_items): need to use g_hash_table_new_full() here too or everything will b0rk. * app/widgets/gimppreviewrenderer.c (gimp_preview_renderer_default_render_stock): use gtk_widget_render_icon() instead of gtk_icon_set_render_icon(). * tools/pdbgen/enums.pl: this file wanted to be regenerated...
2003-03-07 00:47:34 +08:00
return NULL;
/* Ok prime the cache with a large preview if the cache is invalid */
app/core/Makefile.am app/core/core-types.h new base class for something 2002-02-25 Michael Natterer <mitch@gimp.org> * app/core/Makefile.am * app/core/core-types.h * app/core/gimpitem.[ch]: new base class for something which is a child of an image, has a PDB ID, a tattoo, parasites and emits a "removed" signal. * app/core/gimpdrawable.[ch] * app/vectors/gimpvectors.[ch]: derive from GimpItem. Removed lots of stuff from GimpDrawable. * app/core/gimp.[ch]: changed gimp->drawable_table and gimp->next_drawable_ID to gimp->item_table and gimp->next_item_id. * app/undo.[ch]: s/undo_push_drawable_parasite/undo_push_item_parasite/, minor cleanups. * app/core/gimplayer.[ch]: changed gimp_layer_new_from_tiles() and gimp_layer_new_from_drawable() to take the "dest_gimage" as second, not first parameter. * app/image_map.c * app/core/gimpchannel.c * app/core/gimpdrawable-blend.c * app/core/gimpdrawable-bucket-fill.c * app/core/gimpdrawable-histogram.c * app/core/gimpdrawable-offset.c * app/core/gimpdrawable-preview.c * app/core/gimpdrawable-transform.c * app/core/gimpedit.c * app/core/gimpimage-duplicate.c * app/core/gimpimage-mask.c * app/core/gimpimage-merge.c * app/core/gimpimage-pick-color.c * app/core/gimpimage.c * app/core/gimplayer-floating-sel.c * app/display/gimpdisplayshell-dnd.c * app/file/file-save.c * app/gui/channels-commands.c * app/gui/file-save-dialog.c * app/gui/layers-commands.c * app/gui/offset-dialog.c * app/gui/paths-dialog.c * app/gui/toolbox.c * app/paint/gimpairbrush.c * app/paint/gimpclone.c * app/paint/gimpconvolve.c * app/paint/gimpdodgeburn.c * app/paint/gimperaser.c * app/paint/gimppaintbrush.c * app/paint/gimppaintcore.c * app/paint/gimppencil.c * app/paint/gimpsmudge.c * app/plug-in/plug-in.c * app/tools/gimpbezierselecttool.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpinktool.c * app/tools/gimppainttool.c * app/xcf/xcf-load.c * app/xcf/xcf-save.c * app/widgets/gimpdrawablepreview.c: changed accordingly. * app/widgets/Makefile.am * app/widgets/widgets-types.h * app/widgets/gimpitemlistview.[ch]: new widget implementing most of the stuff formerly done by GimpDrawableListView. * app/widgets/gimpchannellistview.c * app/widgets/gimpdrawablelistitem.c * app/widgets/gimpdrawablelistview.[ch] * app/widgets/gimplayerlistview.c: changed accordingly. * app/widgets/gimpdnd.[ch]: added a vectors DND type. * app/gui/menus.c * app/gui/dialogs.c * app/gui/dialogs-constructors.[ch]: added a vectors dialog and a vectors item_factory. * app/gui/Makefile.am * app/gui/vectors-commands.[ch]: new files implementing the callbacks for the new vectors dialog and item_factory. * app/pdb/pdb_glue.h: some more ugly hacks to keep intermediate perl code working... * tools/pdbgen/pdb.pl: added a vectors type, use GimpItem for all ID lookups. * tools/pdbgen/pdb/channel.pdb * tools/pdbgen/pdb/color.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/edit.pdb * tools/pdbgen/pdb/image.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/misc_tools.pdb * tools/pdbgen/pdb/parasite.pdb * tools/pdbgen/pdb/selection.pdb * tools/pdbgen/pdb/selection_tools.pdb: misc changes according to stuff above. * app/pdb/channel_cmds.c * app/pdb/color_cmds.c * app/pdb/drawable_cmds.c * app/pdb/edit_cmds.c * app/pdb/floating_sel_cmds.c * app/pdb/image_cmds.c * app/pdb/layer_cmds.c * app/pdb/misc_tools_cmds.c * app/pdb/paint_tools_cmds.c * app/pdb/parasite_cmds.c * app/pdb/selection_cmds.c * app/pdb/selection_tools_cmds.c * app/pdb/text_tool_cmds.c * app/pdb/transform_tools_cmds.c: regenerated.
2002-02-26 01:58:50 +08:00
if (! drawable->preview_valid &&
width <= PREVIEW_CACHE_PRIME_WIDTH &&
height <= PREVIEW_CACHE_PRIME_HEIGHT &&
gimage &&
gimage->width > PREVIEW_CACHE_PRIME_WIDTH &&
gimage->height > PREVIEW_CACHE_PRIME_HEIGHT)
{
TempBuf *tb = gimp_drawable_preview_private (drawable,
PREVIEW_CACHE_PRIME_WIDTH,
PREVIEW_CACHE_PRIME_HEIGHT);
/* Save the 2nd call */
if (width == PREVIEW_CACHE_PRIME_WIDTH &&
height == PREVIEW_CACHE_PRIME_HEIGHT)
return tb;
}
/* Second call - should NOT visit the tile cache...*/
return gimp_drawable_preview_private (drawable, width, height);
}
gint
gimp_drawable_preview_bytes (GimpDrawable *drawable)
{
GimpImageBaseType base_type;
gint bytes = 0;
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), 0);
base_type = GIMP_IMAGE_TYPE_BASE_TYPE (gimp_drawable_type (drawable));
switch (base_type)
{
case GIMP_RGB:
case GIMP_GRAY:
bytes = gimp_drawable_bytes (drawable);
break;
case GIMP_INDEXED:
bytes = gimp_drawable_has_alpha (drawable) ? 4 : 3;
break;
}
return bytes;
}
TempBuf *
gimp_drawable_get_sub_preview (GimpDrawable *drawable,
gint src_x,
gint src_y,
gint src_width,
gint src_height,
gint dest_width,
gint dest_height)
{
GimpItem *item;
GimpImage *gimage;
TempBuf *preview_buf;
PixelRegion srcPR;
PixelRegion destPR;
gint bytes;
gint subsample;
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
g_return_val_if_fail (src_x >= 0, NULL);
g_return_val_if_fail (src_y >= 0, NULL);
g_return_val_if_fail (src_width > 0, NULL);
g_return_val_if_fail (src_height > 0, NULL);
g_return_val_if_fail (dest_width > 0, NULL);
g_return_val_if_fail (dest_height > 0, NULL);
item = GIMP_ITEM (drawable);
g_return_val_if_fail ((src_x + src_width) <= gimp_item_width (item), NULL);
g_return_val_if_fail ((src_y + src_height) <= gimp_item_height (item), NULL);
gimage = gimp_item_get_image (item);
if (! gimage->gimp->config->layer_previews)
return NULL;
bytes = gimp_drawable_preview_bytes (drawable);
/* calculate 'acceptable' subsample */
subsample = 1;
while ((dest_width * (subsample + 1) * 2 < src_width) &&
(dest_height * (subsample + 1) * 2 < src_width))
subsample += 1;
pixel_region_init (&srcPR, gimp_drawable_data (drawable),
src_x, src_y, src_width, src_height,
FALSE);
preview_buf = temp_buf_new (dest_width, dest_height, bytes, 0, 0, NULL);
destPR.bytes = preview_buf->bytes;
destPR.x = 0;
destPR.y = 0;
destPR.w = dest_width;
destPR.h = dest_height;
destPR.rowstride = dest_width * destPR.bytes;
destPR.data = temp_buf_data (preview_buf);
if (GIMP_IS_LAYER (drawable))
{
gimp_drawable_preview_scale (gimp_drawable_type (drawable),
gimp_image_get_colormap (gimage),
&srcPR, &destPR,
subsample);
}
else if (GIMP_IS_CHANNEL (drawable))
{
subsample_region (&srcPR, &destPR, subsample);
}
return preview_buf;
}
/* private functions */
static TempBuf *
gimp_drawable_preview_private (GimpDrawable *drawable,
gint width,
gint height)
{
2003-09-06 01:44:39 +08:00
TempBuf *ret_buf;
if (! drawable->preview_valid ||
! (ret_buf = gimp_preview_cache_get (&drawable->preview_cache,
width, height)))
{
GimpItem *item = GIMP_ITEM (drawable);
2003-09-06 01:44:39 +08:00
ret_buf = gimp_drawable_get_sub_preview (drawable,
0, 0,
gimp_item_width (item),
gimp_item_height (item),
width,
height);
if (! drawable->preview_valid)
gimp_preview_cache_invalidate (&drawable->preview_cache);
drawable->preview_valid = TRUE;
gimp_preview_cache_add (&drawable->preview_cache, ret_buf);
}
return ret_buf;
}
static void
gimp_drawable_preview_scale (GimpImageType type,
const guchar *cmap,
PixelRegion *srcPR,
PixelRegion *destPR,
gint subsample)
{
#define EPSILON 0.000001
guchar *src, *s;
guchar *dest, *d;
gdouble *row, *r;
gint destwidth;
gint src_row, src_col;
gint bytes, b;
gint width, height;
gint orig_width, orig_height;
gdouble x_rat, y_rat;
gdouble x_cum, y_cum;
gdouble x_last, y_last;
gdouble *x_frac, y_frac, tot_frac;
gint i, j;
gint frac;
gboolean advance_dest;
gboolean has_alpha;
g_return_if_fail (! GIMP_IMAGE_TYPE_IS_INDEXED (type) || cmap != NULL);
orig_width = srcPR->w / subsample;
orig_height = srcPR->h / subsample;
width = destPR->w;
height = destPR->h;
/* Some calculations... */
bytes = destPR->bytes;
destwidth = destPR->rowstride;
has_alpha = GIMP_IMAGE_TYPE_HAS_ALPHA (type);
/* the data pointers... */
src = g_new (guchar, orig_width * bytes);
dest = destPR->data;
/* find the ratios of old x to new x and old y to new y */
x_rat = (gdouble) orig_width / (gdouble) width;
y_rat = (gdouble) orig_height / (gdouble) height;
/* allocate an array to help with the calculations */
row = g_new0 (gdouble, width * bytes);
x_frac = g_new (gdouble, width + orig_width);
/* initialize the pre-calculated pixel fraction array */
src_col = 0;
x_cum = (gdouble) src_col;
x_last = x_cum;
for (i = 0; i < width + orig_width; i++)
{
if (x_cum + x_rat <= (src_col + 1 + EPSILON))
{
x_cum += x_rat;
x_frac[i] = x_cum - x_last;
}
else
{
src_col++;
x_frac[i] = src_col - x_last;
}
x_last += x_frac[i];
}
/* counters... */
src_row = 0;
y_cum = (gdouble) src_row;
y_last = y_cum;
pixel_region_get_row (srcPR,
srcPR->x,
srcPR->y + src_row * subsample,
orig_width * subsample,
src,
subsample);
/* Scale the selected region */
for (i = 0; i < height; )
{
src_col = 0;
x_cum = (gdouble) src_col;
/* determine the fraction of the src pixel we are using for y */
if (y_cum + y_rat <= (src_row + 1 + EPSILON))
{
y_cum += y_rat;
y_frac = y_cum - y_last;
advance_dest = TRUE;
}
else
{
src_row++;
y_frac = src_row - y_last;
advance_dest = FALSE;
}
y_last += y_frac;
s = src;
r = row;
frac = 0;
j = width;
while (j)
{
tot_frac = x_frac[frac++] * y_frac;
/* If indexed, transform the color to RGB */
if (GIMP_IMAGE_TYPE_IS_INDEXED (type))
{
2003-09-06 01:44:39 +08:00
gint index = *s * 3;
if (has_alpha)
{
if (s[ALPHA_I_PIX] & 0x80)
{
r[RED_PIX] += cmap[index++] * tot_frac;
r[GREEN_PIX] += cmap[index++] * tot_frac;
r[BLUE_PIX] += cmap[index++] * tot_frac;
r[ALPHA_PIX] += tot_frac;
}
/* else the pixel contributes nothing and needs
* not to be added
*/
}
else
{
r[RED_PIX] += cmap[index++] * tot_frac;
r[GREEN_PIX] += cmap[index++] * tot_frac;
r[BLUE_PIX] += cmap[index++] * tot_frac;
}
}
else
{
if (has_alpha)
{
/* premultiply */
gdouble local_frac = tot_frac * (gdouble) s[bytes - 1] / 255.0;
for (b = 0; b < (bytes - 1); b++)
r[b] += s[b] * local_frac;
r[bytes - 1] += local_frac;
}
else
{
for (b = 0; b < bytes; b++)
r[b] += s[b] * tot_frac;
}
}
/* increment the destination */
if (x_cum + x_rat <= (src_col + 1 + EPSILON))
{
r += bytes;
x_cum += x_rat;
j--;
}
/* increment the source */
else
{
s += srcPR->bytes;
src_col++;
}
}
if (advance_dest)
{
tot_frac = 1.0 / (x_rat * y_rat);
/* copy "row" to "dest" */
d = dest;
r = row;
j = width;
while (j--)
{
if (has_alpha)
{
/* unpremultiply */
gdouble alpha = r[bytes - 1];
if (alpha > EPSILON)
{
for (b = 0; b < (bytes - 1); b++)
d[b] = (guchar) ((r[b] / alpha) + 0.5);
d[bytes - 1] = (guchar) ((alpha * tot_frac * 255.0) + 0.5);
}
else
{
for (b = 0; b < bytes; b++)
d[b] = 0;
}
}
else
{
for (b = 0; b < bytes; b++)
d[b] = (guchar) ((r[b] * tot_frac) + 0.5);
}
r += bytes;
d += bytes;
}
dest += destwidth;
/* clear the "row" array */
memset (row, 0, sizeof (gdouble) * destwidth);
i++;
}
else
{
pixel_region_get_row (srcPR,
srcPR->x,
srcPR->y + src_row * subsample,
orig_width * subsample,
src,
subsample);
}
}
/* free up temporary arrays */
g_free (row);
g_free (x_frac);
g_free (src);
}