1. 22 Apr, 2018 1 commit
    • Ell's avatar
      Bug 795410 - Deleting a layer group and then undoing the deletion ... · 37742a9f
      Ell authored
      ... raises a CRITICAL
      
      gimp_item_{start,end}_move() currently serves two different
      purposes:  It is used by GimpLayer to suspend/resume mask resizing
      of the layer's ancestors; this is necessary whenever an operation
      on a layer might affect the size of its ancestors.  It is also used
      by GimpGroupLayer to suspend/resume its own mask resizing; this, on
      the other hand, is only necessary before applying one of the
      transformation functions to the group, so that mask modification is
      handled by GimpLayer.  In other words, the effects of
      gimp_item_{start,end}_move() on group layers are only necessary in
      a subset of the cases in which these functions are used.
      
      While in itself this isn't a problem, it does cause issues when
      removing a group layer:  gimp_image_remove_layer() calls
      gimp_item_start_move() before removing the layer, and
      gimp_item_end_move() afterwards.  While the former function is
      called while the layer is still attached to the image, the latter
      function is called after the layer is no longer attached.  Since
      GimpGroupLayer pushes an undo step in response to these calls, only
      the call to start_move() results in an undo step, while the call to
      end_move() doesn't, resulting in an unbalanced
      GIMP_UNDO_GROUP_LAYER_START_MOVE undo step on the stack.  This
      causes problems when undoing the operation.
      
      Add gimp_item_{start,end}_transform() functions, and corresponding
      GimpItem::{start,end}_transform() virtual functions, which are more
      specialized versions of gimp_item_{start,end}_move(), which should
      be used instead of the former before/after transforming an item; in
      other cases, such as when removing ot reordering an item,
      gimp_item_{start,end}_move() should still be used.  The default
      implementation of GimpItem::{start,end}_transform() calls
      gimp_item_{start,end}_move(), respectively, so subclasses that
      override these functions don't have to do that themselves.
      
      In GimpGroupLayer, override GimpItem::{start,end}_transform(),
      instead of GimpItem::{start,end}_move(), for the same purpose of
      suspending mask resize.  This avoids these functions from being
      called when removing a layer group, fixing the bug.
      37742a9f
  2. 25 Mar, 2018 1 commit
    • Ell's avatar
      app: fix layer-group mask cropping during move operation undo · 76a88cc6
      Ell authored
      In gimp_group_layer_{start,end}_move(), push corresponding undo
      steps, which perform the opposite operation during undo, and make
      sure that mask-cropping is frozen during group-layer move
      operations.
      
      This fixed erroneous group-layer mask cropping when undoing/redoing
      a group-layer move operation multiple times.
      76a88cc6
  3. 05 Feb, 2018 2 commits
    • Ell's avatar
      app: fix undo when resizing a group layer with a mask · e7a2624a
      Ell authored
      Override GimpItem::resize(), instead of GimpLayer::resize(), when
      resizing a group layer, so that GimpLayer doesn't try to resize the
      mask.  Instead, the let the usual mask resizing logic in
      GimpGroupLayer handle that.
      
      Also, make sure that the mask is properly restored upon undo when
      group resizing is suspended outside of any mask-suspension block,
      which can happen when resizing the group.
      e7a2624a
    • Ell's avatar
      Bug 51112 - Support layer masks on layer groups · 36dec4e6
      Ell authored
      Add layer-mask support for group layers.  Group-layer masks work
      similarly to ordinary-layer masks, with the following
      considerations:
      
      The group's mask size is the same as group's size (i.e., the
      bounding box of its children) at all times.  When the group's size
      changes, the mask is cropped to the new size -- areas of the mask
      that fall outside of the new bounds are discarded and their data is
      lost (sans undo), and newly added areas are filled with black (and
      hence are transparent by default).
      
      The new gimp_group_layer_{suspend,resume}_mask() functions can be
      used to modify this behavior.  Between the outermost pair of
      suspend/resume calls, the old mask data is remembered, and is used
      to fill the newly added areas while cropping the mask when the
      group is resized.  We override GimpItem::{start,end}_move() for
      GimpLayer, to call these functions (suspend() in start_move(), and
      resume() in end_move()) for each of the layer's ancestors.
      
      As a result, while moving a layer, or a set of layers, atomically,
      such as while dragging with the move tool, or moving linked layers,
      the ancestors' mask data is not lost, and is only discarded at the
      end of the operation.
      
      This commit also takes care of properly handling undo for group-
      layer mask crops, properly invalidating the image when the group
      layer's mask is shown, and enabling the mask actions for group
      layers (obviously :).
      36dec4e6
  4. 22 Jan, 2018 2 commits
    • Jehan's avatar
      app: all remaining g_assert() replaced by critical warning and return... · 4c2df9b3
      Jehan authored
      ... in app/core.
      Continuing on my crusade against asserting and crashing GIMP.
      4c2df9b3
    • Jehan's avatar
      app: we should not have any g_assert*() code if possible. · f87bc3fe
      Jehan authored
      Replace all g_assert_not_reached() in app/core/ by g_return_if_reached()
      or g_return_val_if_reached(). GIMP may handle a lot of creative work,
      sometimes unsaved for hours. We should not just crash on purpose.
      g_assert*() could theoretically be turned off on a glib build, but this
      is nearly never done, and is not a solution either (actually it is
      probably even worse because the broken code would just continue on a
      forbidden path). It is much better to return with a warning on such
      forbidden code paths, allowing someone to report a bug without
      experiencing a crash and data loss.
      
      For now, I only took care of g_assert_not_reached() inside app/core.
      More g_assert*() code should be replaced.
      Note: assert are acceptable in plug-ins though, but not in the main
      executable, unless absolutely necessary (something happening so bad that
      crash is better than continuing).
      f87bc3fe
  5. 03 Oct, 2016 1 commit
  6. 21 Oct, 2015 1 commit
  7. 16 Aug, 2015 1 commit
    • Michael Natterer's avatar
      app: add "gboolean convert_profile" to GimpDrawable::convert_type() · 76782e62
      Michael Natterer authored
      also add "GType old_type" to GimpItem::convert() so implementations
      can do things depending on the type of the original item.
      
      In gimp_layer_convert(), if the original item is also a layer, and
      color management is not off (with a FIXME because this is the wrong
      check), pass convert_profile = TRUE to gimp_drawable_convert_type().
      
      There is no color profile conversion anywhere behind this, this is
      just an API change commit.
      76782e62
  8. 14 Oct, 2013 1 commit
    • Michael Natterer's avatar
      app,libgimp*: fix includes to follow our include policy · 697572cc
      Michael Natterer authored
      - don't include <gdk-pixbuf/gdk-pixbuf.h> in headers in app/
      - instead, include it in many .c files instead of <glib-object.h>,
        finally acknowledging the fact that app/ depends on gdk-pixbuf almost
        globally
      - fix up includes as if libgimpbase depended in GIO, which it soon will
      697572cc
  9. 12 Nov, 2012 1 commit
  10. 13 Oct, 2012 1 commit
  11. 02 May, 2012 3 commits
  12. 12 Jan, 2011 1 commit
  13. 13 Sep, 2009 1 commit
    • Michael Natterer's avatar
      Fix undoing a group layer type conversion · 717b4e6a
      Michael Natterer authored
      * app/core/gimpdrawable.[ch]: add "gboolean push_undo" to
        GimpDrawable::convert_type().
      
      * app/core/gimpdrawable-convert.[ch]: same here for the gray and rgb
        conversion functions.
      
      * app/core/gimpchannel.c
      * app/core/gimplayer.c: pass FALSE when called from GimpItem::convert()
        because it can be called on unattached items only.
      
      * app/core/gimpimage-convert.c: pass TRUE.
      
      * app/core/core-enums.[ch]
      * app/core/gimpgrouplayerundo.[ch]
      * app/core/gimpimage-undo-push.[ch]: add GIMP_UNDO_GROUP_LAYER_CONVERT
        which simply calls gimp_drawable_convert_type() with the old type
        when undone/redone.
      
      * app/core/gimpgrouplayer.c: push a group layer convert undo so this
        can be properly undone/redone.
      717b4e6a
  14. 07 Sep, 2009 1 commit
    • Michael Natterer's avatar
      Add facility to compress multiple group layer resizings into one · 4df9b252
      Michael Natterer authored
      * app/core/gimpgrouplayer.[ch]: add gimp_group_layer_suspend_resize()
        and gimp_group_layer_resume_resize() and call them around functions
        where all a group's children are transformed (translated, resized
        etc).  This way we go from the worst case of reallocating the
        group's projection tiles once for each child down to exactly one
        reallocation.
      
      * app/core/Makefile.am
      * app/core/core-enums.[ch]
      * app/core/core-types.h
      * app/core/gimpimage-undo-push.[ch]
      * app/core/gimpgrouplayerundo.[ch]: add new undo class
        GimpGroupLayerUndo which implements undos for suspend/resume of
        group layers and calls them in reverse order when undoing.
      4df9b252