1. 07 Oct, 2018 1 commit
    • Michael Natterer's avatar
      app: remove the image's "Enable Color Management" toggle · c399b894
      Michael Natterer authored
      It was not doing anything right since space invasion. We now treat the
      built-in sRGB profile like any other profile and never bypass
      conversions based on some weird toggle.
      
      Instead, introduce a "Use sRGB Profile" toggle which, when enabled,
      hides whatever profile away so the image actually uses the built-in
      sRGB profile.
      
      This is different from discarding and then re-assigning the same
      profile only by being faster and more convenient.
      c399b894
  2. 09 Aug, 2018 1 commit
  3. 05 Aug, 2018 1 commit
    • Michael Natterer's avatar
      Issue #1954 - GIMP-2.99 color changes when converting between... · 8226265b
      Michael Natterer authored
      ...linear and perceptual precision
      
      Under certain circumstances (e.g. the image has no color profile),
      GimpLayer's implementation of GimpDrawable::convert_type() didn't have
      enough information to do the right color space conversion.
      
      Intead of messing with stuff like "set profile in between doing a and b",
      simply add a "src_profile" parameter to GimpDrawable::convert_type() so
      the complete color space conversion information is available without
      relying on obscure states that could change in the future.
      
      Make sure all callers pass the right src_profile, particularly in
      gimp_image_convert_precision(), which also needed fixing.
      8226265b
  4. 01 Aug, 2018 1 commit
    • Ell's avatar
      Issue #1884 - Incorrect font when export to png · a826a193
      Ell authored
      In gimp_layer_convert(), avoid converting the drawable type when
      the source and destination color profiles are equal, if otherwise
      unnecessary.  Otherwise, text layers get unnecessarily re-rendered
      during conversion, and, by extension, during image duplication
      (which happens when exporting to any format that requires merging
      down the image).  This may cause the text layer to appear
      differently in the duplicated image, or even use a different font
      if the original font doesn't exist.
      a826a193
  5. 24 Jul, 2018 1 commit
  6. 21 Jul, 2018 1 commit
    • Michael Natterer's avatar
      Initial space invasion commit in GIMP · e09e563a
      Michael Natterer authored
      All babl formats now have a space equivalent to a color profile,
      determining the format's primaries and TRCs. This commit makes GIMP
      aware of this.
      
      libgimp:
      
      - enum GimpPrecision: rename GAMMA values to NON_LINEAR and keep GAMMA
        as deprecated aliases, add PERCEPTUAL values so we now have LINEAR,
        NON_LINEAR and PERCPTUAL for each encoding, matching the babl
        encoding variants RGB, R'G'B' and R~G~B~.
      
      - gimp_color_transform_can_gegl_copy() now returns TRUE if both
        profiles can return a babl space, increasing the amount of fast babl
        color conversions significantly.
      
      - TODO: no solution yet for getting libgimp drawable proxy buffers in
        the right format with space.
      
      plug-ins:
      
      - follow the GimpPrecision change.
      
      - TODO: everything else unchanged and partly broken or sub-optimal,
        like setting a new image's color profile too late.
      
      app:
      
      - add enum GimpTRCType { LINEAR, NON_LINEAR, PERCEPTUAL } as
        replacement for all "linear" booleans.
      
      - change gimp-babl functions to take babl spaces and GimpTRCType
        parameters and support all sorts of new perceptual ~ formats.
      
      - a lot of places changed in the early days of goat invasion didn't
        take advantage of gimp-babl utility functions and constructed
        formats manually. They all needed revisiting and many now use much
        simpler code calling gimp-babl API.
      
      - change gimp_babl_format_get_color_profile() to really extract a
        newly allocated color profile from the format, and add
        gimp_babl_get_builtin_color_profile() which does the same as
        gimp_babl_format_get_color_profile() did before. Visited all callers
        to decide whether they are looking for the format's actual profile,
        or for one of the builtin profiles, simplifying code that only needs
        builtin profiles.
      
      - drawables have a new get_space_api(), get_linear() is now get_trc().
      
      - images now have a "layer space" and an API to get it,
        gimp_image_get_layer_format() returns formats in that space.
      
      - an image's layer space is created from the image's color profile,
        change gimpimage-color-profile to deal with that correctly
      
      - change many babl_format() calls to babl_format_with_space() and take
        the space from passed formats or drawables
      
      - add function gimp_layer_fix_format_space() which replaces the
        layer's buffer with one that has the image's layer format, but
        doesn't change pixel values
      
      - use gimp_layer_fix_format_space() to make sure layers loaded from
        XCF and created by plug-ins have the right space when added to the
        image, because it's impossible to always assign the right space upon
        layer creation
      
      - "assign color profile" and "discard color profile" now require use
        of gimp_layer_fix_format_space() too because the profile is now
        embedded in all formats via the space.  Add
        gimp_image_assign_color_profile() which does all that and call it
        instead of a simple gimp_image_set_color_profile(), also from the
        PDB set-color-profile functions, which are essentially "assign" and
        "discard" calls.
      
      - generally, make sure a new image's color profile is set before
        adding layers to it, gimp_image_set_color_profile() is more than
        before considered know-what-you-are-doing API.
      
      - take special precaution in all places that call
        gimp_drawable_convert_type(), we now must pass a new_profile from
        all callers that convert layers within the same image (such as
        image_convert_type, image_convert_precision), because the layer's
        new space can't be determined from the image's layer format during
        the call.
      
      - change all "linear" properties to "trc", in all config objects like
        for levels and curves, in the histogram, in the widgets. This results
        in some GUI that now has three choices instead of two.
        TODO: we might want to reduce that back to two later.
      
      - keep "linear" boolean properties around as compat if needed for file
        pasring, but always convert the parsed parsed boolean to
        GimpTRCType.
      
      - TODO: the image's "enable color management" switch is currently
        broken, will fix that in another commit.
      e09e563a
  7. 11 Jul, 2018 1 commit
  8. 19 Jun, 2018 1 commit
    • Michael Natterer's avatar
      Issue #1677 - Alpha channel copy / Layer Mask issues · f815a2d9
      Michael Natterer authored
      gimp_layer_create_mask(): make sure we don't do a gamma conversion
      when initializing the mask from a channel. This was probably not the
      last place to need this fix.
      
      Also get rid of a second switch(add_mask_type), must be some leftover
      from long gone logic.
      f815a2d9
  9. 15 Jun, 2018 1 commit
  10. 01 Jun, 2018 1 commit
  11. 25 May, 2018 1 commit
  12. 12 May, 2018 1 commit
  13. 22 Apr, 2018 1 commit
  14. 25 Mar, 2018 1 commit
    • Ell's avatar
      app: use GimpObjectQueue in lots of places · 139a2345
      Ell authored
      Use GimpObjectQueue, added in the previous commit, in various
      instances where we perform an action on a set of objects.  This
      improves progress reporting, by using a single progress for the
      entire operation, rather than reporting the progress of each object
      individually, and by taking the relative cost of each object into
      account, instead of assuming a uniform cost for all objects.
      
      In particular, this affects the various whole-image operations
      (i.e., transformations and color conversions), operations on linked
      items, and operations on layer groups.  This also affects layers
      with masks, whose progress is now reported together instead of
      individually.
      
      Additionally, this commit fixes erroneous group-layer mask cropping
      during undo when resizing the image, by properly calling
      {start,end}_move() on all the resized layers before starting the
      operation, and when scaling the image, by only scaling top-level
      layers, and letting group layers scale their children themselves.
      139a2345
  15. 14 Mar, 2018 1 commit
    • Ell's avatar
      app, pdb, libgimp, plug-ins, menus: rename layer composite modes · a7f3a2dd
      Ell authored
      Our composite modes don't correspond directly to the Porter-Duff
      operators after which they're named, and these names aren't too
      descriptive anyway.
      
      Rename the composite modes as follows:
      
        Source Over       =>  Union
        Source Atop       =>  Clip to Backdrop
        Destination Atop  =>  Clip to Layer
        Source In         =>  Intersection
      
      Update relevant code, including UI text, enumerator names, function
      names, and action names.
      a7f3a2dd
  16. 21 Feb, 2018 1 commit
  17. 14 Feb, 2018 1 commit
    • Ell's avatar
      app: don't allow setting NULL buffer to drawables; modify steal_buffer() · 91a947bb
      Ell authored
      Revert commit 24fcabc1, which
      allowed passing a NULL buffer to gimp_drawable_set_buffer[_full](),
      leaving the drawable without a buffer in a semi-functional state --
      this is too risky.
      
      Instead, have gimp_drawable_steal_buffer() assign an empty 1x1
      buffer to the stolen-from drawable, rather than leaving it without
      a buffer at all.
      91a947bb
  18. 13 Feb, 2018 1 commit
    • Ell's avatar
      app: allow passing a NULL buffer to gimp_drawable_set_buffer[_full]() · 24fcabc1
      Ell authored
      ... which clears the drawable's buffer, performing any necessary
      cleanup, without setting a new buffer.  While the drawable has no
      buffer, it can only be used in a very limited way, in particular,
      it may be destroyed, and it may be assigned a new buffer.
      
      This is used by the next commit to implement
      gimp_drawable_steal_buffer(), which transfers a buffer from one
      drawable to another in a safe manner, leaving the source drawable
      empty.
      24fcabc1
  19. 12 Feb, 2018 2 commits
    • Ell's avatar
      Bug 793373 - Crash when ctrl-alt-clicking, dragging then releasing... · 68e37f28
      Ell authored
      ... a selection.
      
      The crash was the result of an unmatched gimp_item_end_move() call,
      which is an error.  Add the matching gimp_item_start_move() call
      when starting to drag a selection in GimpEditSelectionTool.  Revert
      last commit, so that unmatched gimp_layer_end_move() calls are not
      silently ignored, and add a check instead.
      68e37f28
    • Jehan's avatar
      Bug 793373 - Crash when ctrl-alt-clicking, dragging then releasing... · d9987ea7
      Jehan authored
      ... a selection.
      The regression appeared with commit 10c125c6.
      gimp_layer_end_move() may sometimes run even while a symmetric
      gimp_layer_start_move() had not run. For instance this happens when
      releasing the mouse button after dragging a ctrl-alt-click created
      floating layer.
      Therefore let's check that layer->move_stack is not NULL before
      dereferencing it.
      d9987ea7
  20. 10 Feb, 2018 2 commits
    • Ell's avatar
      app: invalidate channel boundary upon buffer "changed" signal · d0ae244f
      Ell authored
      Have GimpChannel connect to the drawable buffer's "changed" signal,
      so that we can invalidate the channel's boundary whenever the
      buffer contents change.  Currently, the calls to
      gimp_drawable_invalidate_boundary() dispersed throughout the code
      are not enough.
      
      Moreover, invalidate both the boundary and the bounds in
      gimp_channel_invalidate_boundary(), since both are necessary when
      the buffer changes.
      d0ae244f
    • Ell's avatar
      app: keep ancestor set in gimp_layer_start_move(), for use in end_move() · 10c125c6
      Ell authored
      In gimp_layer_start_move(), keep the set of ancestors for which for
      which we suspended mask cropping, so that we can resume mask
      cropping for the same groups in gimp_layer_end_move().  This is
      necessary, since gimp_image_remove_layer() calls gimp_item
      start_move() before removing the layer from the layer tree, and
      gimp_item_end_move() after removing the layer from the layer tree,
      at which point the layer has no ancestors.
      10c125c6
  21. 05 Feb, 2018 2 commits
    • Ell's avatar
      pdb: fail layer-remove-mask if applying a mask to a group layer · 9befb859
      Ell authored
      ... which is not supported.
      9befb859
    • 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
  22. 06 Dec, 2017 1 commit
    • Ell's avatar
      app: add gimp_layer_get_effective_mode() · bdba43e4
      Ell authored
      gimp_layer_get_effective_mode() returns the actual layer mode,
      blend space, comosite space, and composite mode used for the
      layer's mode node, allowing them to be different from the values of
      the corresponding layer properties.  The aim is to allow us to
      replace expensive layer configurations with cheaper but equivalent
      ones transparently.  This is used in the next commit to replace
      pass-through groups with normal groups under certain conditions.
      
      The effective values are computed by the new
      GimpLayer::get_effective_mode() virtual function.  The default
      implementation provided by GimpLayer returns the corresponding
      layer properties as-is (replaceing AUTO with concrete values).
      Subclasses can override this function, providing more
      sophisticated logic.
      bdba43e4
  23. 24 Oct, 2017 1 commit
  24. 21 Oct, 2017 1 commit
    • Ell's avatar
      app: add gimp_layer_get_real_{blend,composite}_{space,mode}() · 96efde0f
      Ell authored
      ... which return the layer's blend/composite space/mode.  However,
      unlike the non-"_real" versions, these functions never return AUTO
      -- instead, they return the actual space/mode that AUTO maps to for
      the current layer mode.
      
      When changing a layer's blend/composite space/mode, avoid
      updating the drawable if the real space/mode didn't change (i.e.,
      if changing from AUTO to the concrete value, or vice versa.)
      96efde0f
  25. 21 Aug, 2017 1 commit
    • Michael Natterer's avatar
      Move the new "default_new_layer_mode" APIs to the image... · e16c8a23
      Michael Natterer authored
      ...in both the core and libgimp.
      
      Images now know what the default mode for new layers is:
      
      - NORMAL for empty images
      - NORMAL for images with any non-legacy layer
      - NORMAL_LEGAVY for images with only legacy layers
      
      This changes behavior when layers are created from the UI, but *also*
      when created by plug-ins (yes there is a compat issue here):
      
      - Most (all?) single-layer file importers now create NORMAL layers
      - Screenshot, Webpage etc also create NORMAL layers
      
      Scripts that create images from scratch (logos etc) should not be
      affected because they usually have NORMAL_LEGACY hardcoded.
      
      3rd party plug-ins and scripts will also behave old-style unless they
      get ported to gimp_image_get_default_new_layer_mode().
      e16c8a23
  26. 20 Aug, 2017 1 commit
  27. 19 Aug, 2017 1 commit
  28. 08 Aug, 2017 2 commits
    • Ell's avatar
      app: move bottom-layer special casing to GimpOperationLayerMode · 3635cf04
      Ell authored
      GimpFilter's is_last_node field only reflects the item's position
      within the parent stack.  When a layer is contained in a pass-
      through group, it can be the last layer of the group, while not
      being the last layer in the graph as a whole (paticularly, if
      there are visible layers below the group).  In fact, when we have
      nested pass-through groups, whether or not a layer is the last
      node depends on which group we're considering as the root (since
      we exclude the backdrop from the group's projection, resulting in
      different graphs for different groups).
      
      Instead of rolling our own graph traversal, just move the relevant
      logic to GimpOperationLayerMode, and let GEGL do the work for us.
      At processing time, we can tell if we're the last node by checking
      if we have any input.
      
      For this to work, GimpOperationLayerMode's process() function needs
      to have control over what's going on.  Replace the derived op
      classes, which override process(), with a call to the layer mode's
      function (as per gimp_layer_mode_get_function()) in
      GimpOperationLayerMode's process() function.  (Well, actually, this
      commit keeps the ops around, and just hacks around them in
      gimp_layer_mode_get_operation(), because laziness :P)
      
      Keep using the layer's is_last_node property to do the invalidation.
      3635cf04
    • Ell's avatar
      app: connect layer backdrop to source node's input · ac319021
      Ell authored
      Make sure the input of the layer's filter node is connected to its
      source node (when it has an input pad), so that, once we implement
      pass-though mode, the group's source node can see the backdrop.
      ac319021
  29. 15 Jul, 2017 1 commit
  30. 17 Jun, 2017 1 commit
    • Ell's avatar
      app: add virtual transform/type-conversion functions to GimpLayer · c83f0e88
      Ell authored
      The GimpLayer implementation of the GimpItem transform functions,
      and the GimpDrawable convert_type() function, apply their operation
      to both the layer and its mask.  The subclasses of GimpLayer --
      GimpGroupLayer and GimpTextLayer -- override some of these
      functions, providing their own logic for the layer part, and
      duplicating the mask part.
      
      Avoid this duplication by adding a set of virtual transform and
      type-conversion functions to GimpLayer.  Have the GimpLayer
      implementaion of the corresponding GimpItem and GimpDrawable
      functions use these functions to apply the operation to the layer,
      while taking care of the mask themselves.  Have GimpLayer's
      subclasses override the new virtual functions, instead of the
      GimpItem and GimpDrawable ones.
      
      Note that the existing implementation of convert_type() in
      GimpTextLayer neglected to convert the mask, hence text layer masks
      retained their old format after conversion.  This issue is fixed as
      a side effect of this commit.
      c83f0e88
  31. 11 May, 2017 1 commit
    • Ell's avatar
      app: add GimpLayer::excludes_backdrop property · a0510022
      Ell authored
      A boolean flag, specifying whether the backdrop is clipped to the
      layer.  That's the case when the layer's composite mode is dst-atop
      or src-in.
      
      This is a read-only property, derived from the other attributes of
      the layer.  We compute its value through a virtual function, so that
      GimpGroupLayer will eventually be able to specialize it for pass-
      through groups.
      
      The next commit uses this property to actually do something useful.
      a0510022
  32. 27 Feb, 2017 1 commit
  33. 26 Feb, 2017 1 commit
  34. 17 Feb, 2017 1 commit
    • Ell's avatar
      app: add GimpLayerModeContext enum · c3d2f57e
      Ell authored
      A bitmask, specifying in which contexts a layer mode is applicable.
      Can be a combination of:
      
        - LAYER: usable as a layer mode for actual layers.
        - GROUP: usable as a layer mode for layer groups.  Currently, all
          modes that specify LAYER also specify GROUP, and vice versa,
          but the planned pass-through mode will be GROUP only.
        - PAINT: can be used as a paint mode.
        - FADE: can be used for fading.
      
      Add a 'context' field to _GimpLayerModeInfo, and provide context
      masks to all the modes.
      
      Use the context mask for validation when setting a layer's mode.
      The next commit will use the mask when populating the layer mode
      menus.
      c3d2f57e
  35. 13 Feb, 2017 1 commit
  36. 12 Feb, 2017 1 commit