[gimp] Issue #40 - Layer offset tool



commit 3a4a00c71e2d40d5e1ec2c9cf7ed2eb47e8db16e
Author: Ell <ell_se yahoo com>
Date:   Wed Jun 5 18:09:28 2019 -0400

    Issue #40 - Layer offset tool
    
    Add a new Offset filter tool, as a front-end to gimp:offset.  The
    tool replaces, and provides the same interface as, the drawable-
    offset dialog, while also providing live preview and on-canvas
    interaction.
    
    Note that we don't simply use a custom propgui constructor for
    gimp:offset, since we need a little more control.

 app/actions/drawable-actions.c               |  10 +-
 app/actions/drawable-commands.c              |  64 ---
 app/actions/drawable-commands.h              |   2 -
 app/actions/filters-actions.c                |   6 +
 app/actions/gimpgeglprocedure.c              |   4 +
 app/dialogs/Makefile.am                      |   2 -
 app/dialogs/dialogs.c                        |   1 +
 app/dialogs/offset-dialog.c                  | 337 ------------
 app/dialogs/offset-dialog.h                  |  38 --
 app/tools/Makefile.am                        |   2 +
 app/tools/gimp-tools.c                       |   4 +-
 app/tools/gimpoffsettool.c                   | 791 +++++++++++++++++++++++++++
 app/tools/gimpoffsettool.h                   |  63 +++
 app/widgets/gimphelp-ids.h                   |   1 +
 icons/Color/16/gimp-tool-offset.png          | Bin 0 -> 792 bytes
 icons/Color/24/gimp-tool-offset.png          | Bin 0 -> 1140 bytes
 icons/Color/24/gimp-tool-offset.svg          | 293 ++++++++++
 icons/Color/color-scalable.svg               | 266 ++++++++-
 icons/Color/icon-list.mk                     |   4 +
 icons/Color/scalable/gimp-tool-offset.svg    | 246 +++++++++
 icons/Symbolic/16/gimp-tool-offset.png       | Bin 0 -> 567 bytes
 icons/Symbolic/24/gimp-tool-offset.png       | Bin 0 -> 723 bytes
 icons/Symbolic/24/gimp-tool-offset.svg       | 161 ++++++
 icons/Symbolic/scalable/gimp-tool-offset.svg | 162 ++++++
 icons/Symbolic/symbolic-scalable.svg         |  70 ++-
 libgimpwidgets/gimpicons.h                   |   1 +
 menus/image-menu.xml.in                      |   2 +-
 po/POTFILES.in                               |   2 +-
 28 files changed, 2070 insertions(+), 462 deletions(-)
---
diff --git a/app/actions/drawable-actions.c b/app/actions/drawable-actions.c
index 541350a008..bd421ee873 100644
--- a/app/actions/drawable-actions.c
+++ b/app/actions/drawable-actions.c
@@ -51,14 +51,7 @@ static const GimpActionEntry drawable_actions[] =
     NC_("drawable-action", "_White Balance"), NULL,
     NC_("drawable-action", "Automatic white balance correction"),
     G_CALLBACK (drawable_levels_stretch_cmd_callback),
-    GIMP_HELP_LAYER_WHITE_BALANCE },
-
-  { "drawable-offset", NULL,
-    NC_("drawable-action", "_Offset..."), "<primary><shift>O",
-    NC_("drawable-action",
-        "Shift the pixels, optionally wrapping them at the borders"),
-    G_CALLBACK (drawable_offset_cmd_callback),
-    GIMP_HELP_LAYER_OFFSET }
+    GIMP_HELP_LAYER_WHITE_BALANCE }
 };
 
 static const GimpToggleActionEntry drawable_toggle_actions[] =
@@ -215,7 +208,6 @@ drawable_actions_update (GimpActionGroup *group,
 
   SET_SENSITIVE ("drawable-equalize",       writable && !children);
   SET_SENSITIVE ("drawable-levels-stretch", writable && !children && is_rgb);
-  SET_SENSITIVE ("drawable-offset",         writable && !children);
 
   SET_SENSITIVE ("drawable-visible",       drawable);
   SET_SENSITIVE ("drawable-linked",        drawable);
diff --git a/app/actions/drawable-commands.c b/app/actions/drawable-commands.c
index 96d1d85952..03afd7141d 100644
--- a/app/actions/drawable-commands.c
+++ b/app/actions/drawable-commands.c
@@ -27,7 +27,6 @@
 #include "core/gimp.h"
 #include "core/gimpdrawable-equalize.h"
 #include "core/gimpdrawable-levels.h"
-#include "core/gimpdrawable-offset.h"
 #include "core/gimpdrawable-operation.h"
 #include "core/gimpimage.h"
 #include "core/gimpimage-undo.h"
@@ -37,7 +36,6 @@
 #include "core/gimpprogress.h"
 
 #include "dialogs/dialogs.h"
-#include "dialogs/offset-dialog.h"
 
 #include "actions.h"
 #include "drawable-commands.h"
@@ -45,17 +43,6 @@
 #include "gimp-intl.h"
 
 
-/*  local function prototypes  */
-
-static void   drawable_offset_callback (GtkWidget      *dialog,
-                                        GimpDrawable   *drawable,
-                                        GimpContext    *context,
-                                        gboolean        wrap_around,
-                                        GimpOffsetType  fill_type,
-                                        gint            offset_x,
-                                        gint            offset_y);
-
-
 /*  public functions  */
 
 void
@@ -95,35 +82,6 @@ drawable_levels_stretch_cmd_callback (GtkAction *action,
   gimp_image_flush (image);
 }
 
-void
-drawable_offset_cmd_callback (GtkAction *action,
-                              gpointer   data)
-{
-  GimpImage    *image;
-  GimpDrawable *drawable;
-  GtkWidget    *widget;
-  GtkWidget    *dialog;
-  return_if_no_drawable (image, drawable, data);
-  return_if_no_widget (widget, data);
-
-#define OFFSET_DIALOG_KEY "gimp-offset-dialog"
-
-  dialog = dialogs_get_dialog (G_OBJECT (drawable), OFFSET_DIALOG_KEY);
-
-  if (! dialog)
-    {
-      dialog = offset_dialog_new (drawable, action_data_get_context (data),
-                                  widget,
-                                  drawable_offset_callback,
-                                  NULL);
-
-      dialogs_attach_dialog (G_OBJECT (drawable),
-                             OFFSET_DIALOG_KEY, dialog);
-    }
-
-  gtk_window_present (GTK_WINDOW (dialog));
-}
-
 void
 drawable_linked_cmd_callback (GtkAction *action,
                               gpointer   data)
@@ -336,25 +294,3 @@ drawable_rotate_cmd_callback (GtkAction *action,
 
   gimp_image_flush (image);
 }
-
-
-/*  private functions  */
-
-static void
-drawable_offset_callback (GtkWidget      *dialog,
-                          GimpDrawable   *drawable,
-                          GimpContext    *context,
-                          gboolean        wrap_around,
-                          GimpOffsetType  fill_type,
-                          gint            offset_x,
-                          gint            offset_y)
-{
-  GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
-
-  gimp_drawable_offset (drawable, context,
-                        wrap_around, fill_type,
-                        offset_x, offset_y);
-  gimp_image_flush (image);
-
-  gtk_widget_destroy (dialog);
-}
diff --git a/app/actions/drawable-commands.h b/app/actions/drawable-commands.h
index ef072c97f9..b678faf359 100644
--- a/app/actions/drawable-commands.h
+++ b/app/actions/drawable-commands.h
@@ -23,8 +23,6 @@ void   drawable_equalize_cmd_callback       (GtkAction *action,
                                              gpointer   data);
 void   drawable_levels_stretch_cmd_callback (GtkAction *action,
                                              gpointer   data);
-void   drawable_offset_cmd_callback         (GtkAction *action,
-                                             gpointer   data);
 
 void   drawable_linked_cmd_callback         (GtkAction *action,
                                              gpointer   data);
diff --git a/app/actions/filters-actions.c b/app/actions/filters-actions.c
index a8d3bd92b9..7e2930993d 100644
--- a/app/actions/filters-actions.c
+++ b/app/actions/filters-actions.c
@@ -523,6 +523,11 @@ static const GimpStringActionEntry filters_interactive_actions[] =
     "gegl:noise-spread",
     GIMP_HELP_FILTER_NOISE_SPREAD },
 
+  { "filters-offset", GIMP_ICON_TOOL_OFFSET,
+    NC_("filters-action", "_Offset..."), "<primary><shift>O", NULL,
+    "gimp:offset",
+    GIMP_HELP_TOOL_OFFSET },
+
   { "filters-oilify", GIMP_ICON_GEGL,
     NC_("filters-action", "Oili_fy..."), NULL, NULL,
     "gegl:oilify",
@@ -922,6 +927,7 @@ filters_actions_update (GimpActionGroup *group,
   SET_SENSITIVE ("filters-noise-slur",              writable);
   SET_SENSITIVE ("filters-noise-solid",             writable);
   SET_SENSITIVE ("filters-noise-spread",            writable);
+  SET_SENSITIVE ("filters-offset",                  writable);
   SET_SENSITIVE ("filters-oilify",                  writable);
   SET_SENSITIVE ("filters-panorama-projection",     writable);
   SET_SENSITIVE ("filters-photocopy",               writable);
diff --git a/app/actions/gimpgeglprocedure.c b/app/actions/gimpgeglprocedure.c
index 2630448417..2e4c5e438c 100644
--- a/app/actions/gimpgeglprocedure.c
+++ b/app/actions/gimpgeglprocedure.c
@@ -339,6 +339,10 @@ gimp_gegl_procedure_execute_async (GimpProcedure  *procedure,
     {
       tool_name = "gimp-threshold-tool";
     }
+  else if (! strcmp (procedure->original_name, "gimp:offset"))
+    {
+      tool_name = "gimp-offset-tool";
+    }
   else
     {
       tool_name = "gimp-operation-tool";
diff --git a/app/dialogs/Makefile.am b/app/dialogs/Makefile.am
index 93045de974..61c2959f9e 100644
--- a/app/dialogs/Makefile.am
+++ b/app/dialogs/Makefile.am
@@ -69,8 +69,6 @@ libappdialogs_a_sources = \
        lebl-dialog.h                   \
        module-dialog.c                 \
        module-dialog.h                 \
-       offset-dialog.c                 \
-       offset-dialog.h                 \
        palette-import-dialog.c         \
        palette-import-dialog.h         \
        preferences-dialog.c            \
diff --git a/app/dialogs/dialogs.c b/app/dialogs/dialogs.c
index 259ce15394..721118671b 100644
--- a/app/dialogs/dialogs.c
+++ b/app/dialogs/dialogs.c
@@ -234,6 +234,7 @@ static const GimpDialogFactoryEntry entries[] =
   FOREIGN ("gimp-hue-saturation-tool-dialog",      TRUE,  FALSE),
   FOREIGN ("gimp-levels-tool-dialog",              TRUE,  TRUE),
   FOREIGN ("gimp-measure-tool-dialog",             TRUE,  FALSE),
+  FOREIGN ("gimp-offset-tool-dialog",              TRUE,  FALSE),
   FOREIGN ("gimp-operation-tool-dialog",           TRUE,  FALSE),
   FOREIGN ("gimp-posterize-tool-dialog",           TRUE,  FALSE),
   FOREIGN ("gimp-rotate-tool-dialog",              TRUE,  FALSE),
diff --git a/app/tools/Makefile.am b/app/tools/Makefile.am
index cd98150c10..a65543ce89 100644
--- a/app/tools/Makefile.am
+++ b/app/tools/Makefile.am
@@ -124,6 +124,8 @@ libapptools_a_sources = \
        gimpiscissorstool.h             \
        gimplevelstool.c                \
        gimplevelstool.h                \
+       gimpoffsettool.c                \
+       gimpoffsettool.h                \
        gimpoperationtool.c             \
        gimpoperationtool.h             \
        gimpmagnifyoptions.c            \
diff --git a/app/tools/gimp-tools.c b/app/tools/gimp-tools.c
index 16d41de588..979b3cff37 100644
--- a/app/tools/gimp-tools.c
+++ b/app/tools/gimp-tools.c
@@ -71,6 +71,7 @@
 #include "gimpmovetool.h"
 #include "gimpmybrushtool.h"
 #include "gimpnpointdeformationtool.h"
+#include "gimpoffsettool.h"
 #include "gimppaintbrushtool.h"
 #include "gimppenciltool.h"
 #include "gimpperspectiveclonetool.h"
@@ -172,12 +173,13 @@ gimp_tools_init (Gimp *gimp)
     gimp_smudge_tool_register,
     gimp_dodge_burn_tool_register,
 
-    /*  color tools  */
+    /*  filter tools  */
 
     gimp_brightness_contrast_tool_register,
     gimp_threshold_tool_register,
     gimp_levels_tool_register,
     gimp_curves_tool_register,
+    gimp_offset_tool_register,
     gimp_gegl_tool_register,
     gimp_operation_tool_register
   };
diff --git a/app/tools/gimpoffsettool.c b/app/tools/gimpoffsettool.c
new file mode 100644
index 0000000000..fdf6c02b1e
--- /dev/null
+++ b/app/tools/gimpoffsettool.c
@@ -0,0 +1,791 @@
+/* GIMP - The GNU 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 3 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, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+
+#include "libgimpmath/gimpmath.h"
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "tools-types.h"
+
+#include "core/gimpchannel.h"
+#include "core/gimpdrawable.h"
+#include "core/gimpdrawablefilter.h"
+#include "core/gimpimage.h"
+#include "core/gimplayer.h"
+#include "core/gimplayermask.h"
+
+#include "widgets/gimphelp-ids.h"
+
+#include "display/gimpdisplay.h"
+#include "display/gimptoolgui.h"
+
+#include "gimpoffsettool.h"
+#include "gimpfilteroptions.h"
+#include "gimptoolcontrol.h"
+
+#include "gimp-intl.h"
+
+
+static gboolean   gimp_offset_tool_initialize            (GimpTool              *tool,
+                                                          GimpDisplay           *display,
+                                                          GError               **error);
+static void       gimp_offset_tool_control               (GimpTool              *tool,
+                                                          GimpToolAction         action,
+                                                          GimpDisplay           *display);
+static void       gimp_offset_tool_button_press          (GimpTool              *tool,
+                                                          const GimpCoords      *coords,
+                                                          guint32                time,
+                                                          GdkModifierType        state,
+                                                          GimpButtonPressType    press_type,
+                                                          GimpDisplay           *display);
+static void       gimp_offset_tool_button_release        (GimpTool              *tool,
+                                                          const GimpCoords      *coords,
+                                                          guint32                time,
+                                                          GdkModifierType        state,
+                                                          GimpButtonReleaseType  release_type,
+                                                          GimpDisplay           *display);
+static void       gimp_offset_tool_motion                (GimpTool              *tool,
+                                                          const GimpCoords      *coords,
+                                                          guint32                time,
+                                                          GdkModifierType        state,
+                                                          GimpDisplay           *display);
+static void       gimp_offset_tool_oper_update           (GimpTool              *tool,
+                                                          const GimpCoords      *coords,
+                                                          GdkModifierType        state,
+                                                          gboolean               proximity,
+                                                          GimpDisplay           *display);
+static void       gimp_offset_tool_cursor_update         (GimpTool              *tool,
+                                                          const GimpCoords      *coords,
+                                                          GdkModifierType        state,
+                                                          GimpDisplay           *display);
+static void       gimp_offset_tool_options_notify        (GimpTool              *tool,
+                                                          GimpToolOptions       *options,
+                                                          const GParamSpec      *pspec);
+
+static gchar    * gimp_offset_tool_get_operation         (GimpFilterTool        *filter_tool,
+                                                          gchar                **description);
+static void       gimp_offset_tool_dialog                (GimpFilterTool        *filter_tool);
+static void       gimp_offset_tool_config_notify         (GimpFilterTool        *filter_tool,
+                                                          GimpConfig            *config,
+                                                          const GParamSpec      *pspec);
+
+static void       gimp_offset_tool_offset_changed        (GimpSizeEntry         *se,
+                                                          GimpOffsetTool        *offset_tool);
+
+static void       gimp_offset_tool_half_xy_clicked       (GtkButton             *button,
+                                                          GimpOffsetTool        *offset_tool);
+static void       gimp_offset_tool_half_x_clicked        (GtkButton             *button,
+                                                          GimpOffsetTool        *offset_tool);
+static void       gimp_offset_tool_half_y_clicked        (GtkButton             *button,
+                                                          GimpOffsetTool        *offset_tool);
+
+static void       gimp_offset_tool_edge_behavior_toggled (GtkToggleButton       *toggle,
+                                                          GimpOffsetTool        *offset_tool);
+
+static void       gimp_offset_tool_background_changed    (GimpContext           *context,
+                                                          const GimpRGB         *color,
+                                                          GimpOffsetTool        *offset_tool);
+
+static gint       gimp_offset_tool_get_width             (GimpOffsetTool        *offset_tool);
+static gint       gimp_offset_tool_get_height            (GimpOffsetTool        *offset_tool);
+
+static void       gimp_offset_tool_update                (GimpOffsetTool        *offset_tool);
+
+static void       gimp_offset_tool_halt                  (GimpOffsetTool        *offset_tool);
+
+
+G_DEFINE_TYPE (GimpOffsetTool, gimp_offset_tool,
+               GIMP_TYPE_FILTER_TOOL)
+
+#define parent_class gimp_offset_tool_parent_class
+
+
+void
+gimp_offset_tool_register (GimpToolRegisterCallback callback,
+                           gpointer                 data)
+{
+  (* callback) (GIMP_TYPE_OFFSET_TOOL,
+                GIMP_TYPE_FILTER_OPTIONS, NULL,
+                GIMP_CONTEXT_PROP_MASK_BACKGROUND,
+                "gimp-offset-tool",
+                _("Offset"),
+                _("Shift the pixels, optionally wrapping them at the borders"),
+                N_("_Offset..."), NULL,
+                NULL, GIMP_HELP_TOOL_OFFSET,
+                GIMP_ICON_TOOL_OFFSET,
+                data);
+}
+
+static void
+gimp_offset_tool_class_init (GimpOffsetToolClass *klass)
+{
+  GimpToolClass       *tool_class        = GIMP_TOOL_CLASS (klass);
+  GimpFilterToolClass *filter_tool_class = GIMP_FILTER_TOOL_CLASS (klass);
+
+  tool_class->initialize           = gimp_offset_tool_initialize;
+  tool_class->control              = gimp_offset_tool_control;
+  tool_class->button_press         = gimp_offset_tool_button_press;
+  tool_class->button_release       = gimp_offset_tool_button_release;
+  tool_class->motion               = gimp_offset_tool_motion;
+  tool_class->oper_update          = gimp_offset_tool_oper_update;
+  tool_class->cursor_update        = gimp_offset_tool_cursor_update;
+  tool_class->options_notify       = gimp_offset_tool_options_notify;
+
+  filter_tool_class->get_operation = gimp_offset_tool_get_operation;
+  filter_tool_class->dialog        = gimp_offset_tool_dialog;
+  filter_tool_class->config_notify = gimp_offset_tool_config_notify;
+}
+
+static void
+gimp_offset_tool_init (GimpOffsetTool *offset_tool)
+{
+  GimpTool *tool = GIMP_TOOL (offset_tool);
+
+  gimp_tool_control_set_scroll_lock (tool->control, TRUE);
+  gimp_tool_control_set_precision   (tool->control,
+                                     GIMP_CURSOR_PRECISION_PIXEL_CENTER);
+}
+
+static gboolean
+gimp_offset_tool_initialize (GimpTool     *tool,
+                             GimpDisplay  *display,
+                             GError      **error)
+{
+  GimpFilterTool *filter_tool = GIMP_FILTER_TOOL (tool);
+  GimpOffsetTool *offset_tool = GIMP_OFFSET_TOOL (tool);
+  GimpContext    *context     = GIMP_CONTEXT (GIMP_TOOL_GET_OPTIONS (tool));
+  GimpImage      *image;
+  gdouble         xres;
+  gdouble         yres;
+
+  if (! GIMP_TOOL_CLASS (parent_class)->initialize (tool, display, error))
+    return FALSE;
+
+  image = gimp_item_get_image (GIMP_ITEM (tool->drawable));
+
+  gimp_image_get_resolution (image, &xres, &yres);
+
+  g_signal_handlers_block_by_func (offset_tool->offset_se,
+                                   gimp_offset_tool_offset_changed,
+                                   offset_tool);
+
+  gimp_size_entry_set_resolution (
+    GIMP_SIZE_ENTRY (offset_tool->offset_se), 0,
+    xres, FALSE);
+  gimp_size_entry_set_resolution (
+    GIMP_SIZE_ENTRY (offset_tool->offset_se), 1,
+    yres, FALSE);
+
+  if (GIMP_IS_LAYER (tool->drawable))
+    gimp_tool_gui_set_description (filter_tool->gui, _("Offset Layer"));
+  else if (GIMP_IS_LAYER_MASK (tool->drawable))
+    gimp_tool_gui_set_description (filter_tool->gui, _("Offset Layer Mask"));
+  else if (GIMP_IS_CHANNEL (tool->drawable))
+    gimp_tool_gui_set_description (filter_tool->gui, _("Offset Channel"));
+  else
+    g_warning ("%s: unexpected drawable type", G_STRFUNC);
+
+  gtk_widget_set_sensitive (offset_tool->transparent_radio,
+                            gimp_drawable_has_alpha (tool->drawable));
+
+  g_signal_handlers_unblock_by_func (offset_tool->offset_se,
+                                     gimp_offset_tool_offset_changed,
+                                     offset_tool);
+
+  gegl_node_set (
+    filter_tool->operation,
+    "context", context,
+    NULL);
+
+  g_signal_connect (context, "background-changed",
+                    G_CALLBACK (gimp_offset_tool_background_changed),
+                    offset_tool);
+
+  gimp_offset_tool_update (offset_tool);
+
+  return TRUE;
+}
+
+static void
+gimp_offset_tool_control (GimpTool       *tool,
+                          GimpToolAction  action,
+                          GimpDisplay    *display)
+{
+  GimpOffsetTool *offset_tool = GIMP_OFFSET_TOOL (tool);
+
+  switch (action)
+    {
+    case GIMP_TOOL_ACTION_PAUSE:
+    case GIMP_TOOL_ACTION_RESUME:
+      break;
+
+    case GIMP_TOOL_ACTION_HALT:
+      gimp_offset_tool_halt (offset_tool);
+      break;
+
+    case GIMP_TOOL_ACTION_COMMIT:
+      break;
+    }
+
+  GIMP_TOOL_CLASS (parent_class)->control (tool, action, display);
+}
+
+static gchar *
+gimp_offset_tool_get_operation (GimpFilterTool  *filter_tool,
+                                gchar          **description)
+{
+  return g_strdup ("gimp:offset");
+}
+
+static void
+gimp_offset_tool_button_press (GimpTool            *tool,
+                               const GimpCoords    *coords,
+                               guint32              time,
+                               GdkModifierType      state,
+                               GimpButtonPressType  press_type,
+                               GimpDisplay         *display)
+{
+  GimpOffsetTool *offset_tool = GIMP_OFFSET_TOOL (tool);
+
+  offset_tool->dragging = ! gimp_filter_tool_on_guide (GIMP_FILTER_TOOL (tool),
+                                                       coords, display);
+
+  if (! offset_tool->dragging)
+    {
+      GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords, time, state,
+                                                    press_type, display);
+    }
+  else
+    {
+      offset_tool->x = coords->x;
+      offset_tool->y = coords->y;
+
+      g_object_get (GIMP_FILTER_TOOL (tool)->config,
+                    "x", &offset_tool->offset_x,
+                    "y", &offset_tool->offset_y,
+                    NULL);
+
+      tool->display = display;
+
+      gimp_tool_control_activate (tool->control);
+
+      gimp_tool_pop_status (tool, display);
+
+      gimp_tool_push_status_coords (tool, display,
+                                    GIMP_CURSOR_PRECISION_PIXEL_CENTER,
+                                    _("Offset: "),
+                                    0,
+                                    ", ",
+                                    0,
+                                    NULL);
+    }
+}
+
+static void
+gimp_offset_tool_button_release (GimpTool              *tool,
+                                 const GimpCoords      *coords,
+                                 guint32                time,
+                                 GdkModifierType        state,
+                                 GimpButtonReleaseType  release_type,
+                                 GimpDisplay           *display)
+{
+  GimpOffsetTool *offset_tool = GIMP_OFFSET_TOOL (tool);
+
+  if (! offset_tool->dragging)
+    {
+      GIMP_TOOL_CLASS (parent_class)->button_release (tool, coords, time, state,
+                                                      release_type, display);
+    }
+  else
+    {
+      gimp_tool_control_halt (tool->control);
+
+      offset_tool->dragging = FALSE;
+
+      if (release_type == GIMP_BUTTON_RELEASE_CANCEL)
+        {
+          g_object_set (GIMP_FILTER_TOOL (tool)->config,
+                        "x", offset_tool->offset_x,
+                        "y", offset_tool->offset_y,
+                        NULL);
+        }
+    }
+}
+
+static void
+gimp_offset_tool_motion (GimpTool         *tool,
+                         const GimpCoords *coords,
+                         guint32           time,
+                         GdkModifierType   state,
+                         GimpDisplay      *display)
+{
+  GimpFilterTool *filter_tool = GIMP_FILTER_TOOL (tool);
+  GimpOffsetTool *offset_tool = GIMP_OFFSET_TOOL (tool);
+
+  if (! offset_tool->dragging)
+    {
+      GIMP_TOOL_CLASS (parent_class)->motion (tool, coords, time, state,
+                                              display);
+    }
+  else
+    {
+      GimpOffsetType type;
+      gint           offset_x;
+      gint           offset_y;
+      gint           x;
+      gint           y;
+      gint           width;
+      gint           height;
+
+      g_object_get (filter_tool->config,
+                    "type", &type,
+                    NULL);
+
+      offset_x = RINT (coords->x - offset_tool->x);
+      offset_y = RINT (coords->y - offset_tool->y);
+
+      x = offset_tool->offset_x + offset_x;
+      y = offset_tool->offset_y + offset_y;
+
+      width  = gimp_offset_tool_get_width  (offset_tool);
+      height = gimp_offset_tool_get_height (offset_tool);
+
+      if (type == GIMP_OFFSET_WRAP_AROUND)
+        {
+          x %= MAX (width,  1);
+          y %= MAX (height, 1);
+        }
+      else
+        {
+          x = CLAMP (x, -width,  +width);
+          y = CLAMP (y, -height, +height);
+        }
+
+      g_object_set (filter_tool->config,
+                    "x", x,
+                    "y", y,
+                    NULL);
+
+      gimp_tool_pop_status (tool, display);
+
+      gimp_tool_push_status_coords (tool, display,
+                                    GIMP_CURSOR_PRECISION_PIXEL_CENTER,
+                                    _("Offset: "),
+                                    offset_x,
+                                    ", ",
+                                    offset_y,
+                                    NULL);
+    }
+}
+
+static void
+gimp_offset_tool_oper_update (GimpTool         *tool,
+                              const GimpCoords *coords,
+                              GdkModifierType   state,
+                              gboolean          proximity,
+                              GimpDisplay      *display)
+{
+  if (! tool->drawable ||
+      gimp_filter_tool_on_guide (GIMP_FILTER_TOOL (tool),
+                                 coords, display))
+    {
+      GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state,
+                                                   proximity, display);
+    }
+  else
+    {
+      gimp_tool_pop_status (tool, display);
+
+      gimp_tool_push_status (tool, display, "%s",
+                             _("Click-Drag to offset drawable"));
+    }
+}
+
+static void
+gimp_offset_tool_cursor_update (GimpTool         *tool,
+                                const GimpCoords *coords,
+                                GdkModifierType   state,
+                                GimpDisplay      *display)
+{
+  if (! tool->drawable ||
+      gimp_filter_tool_on_guide (GIMP_FILTER_TOOL (tool),
+                                 coords, display))
+    {
+      GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state,
+                                                     display);
+    }
+  else
+    {
+      gimp_tool_set_cursor (tool, display,
+                            GIMP_CURSOR_MOUSE,
+                            GIMP_TOOL_CURSOR_MOVE,
+                            GIMP_CURSOR_MODIFIER_NONE);
+    }
+}
+
+static void
+gimp_offset_tool_options_notify (GimpTool         *tool,
+                                 GimpToolOptions  *options,
+                                 const GParamSpec *pspec)
+{
+  GimpOffsetTool *offset_tool = GIMP_OFFSET_TOOL (tool);
+
+  GIMP_TOOL_CLASS (parent_class)->options_notify (tool, options, pspec);
+
+  if (! strcmp (pspec->name, "region"))
+    gimp_offset_tool_update (offset_tool);
+}
+
+static void
+gimp_offset_tool_dialog (GimpFilterTool *filter_tool)
+{
+  GimpOffsetTool *offset_tool = GIMP_OFFSET_TOOL (filter_tool);
+  GtkWidget      *main_vbox;
+  GtkWidget      *vbox;
+  GtkWidget      *hbox;
+  GtkWidget      *button;
+  GtkWidget      *spinbutton;
+  GtkWidget      *frame;
+  GtkAdjustment  *adjustment;
+
+  main_vbox = gimp_filter_tool_dialog_get_vbox (filter_tool);
+
+  /*  The offset frame  */
+  frame = gimp_frame_new (_("Offset"));
+  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
+  gtk_widget_show (frame);
+
+  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+  gtk_container_add (GTK_CONTAINER (frame), vbox);
+  gtk_widget_show (vbox);
+
+  adjustment = (GtkAdjustment *)
+    gtk_adjustment_new (1, 1, 1, 1, 10, 0);
+  spinbutton = gimp_spin_button_new (adjustment, 1.0, 2);
+  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
+  gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), 10);
+
+  offset_tool->offset_se = gimp_size_entry_new (1, GIMP_UNIT_PIXEL, "%a",
+                                                TRUE, TRUE, FALSE, 10,
+                                                GIMP_SIZE_ENTRY_UPDATE_SIZE);
+
+  gimp_size_entry_add_field (GIMP_SIZE_ENTRY (offset_tool->offset_se),
+                             GTK_SPIN_BUTTON (spinbutton), NULL);
+  gtk_grid_attach (GTK_GRID (offset_tool->offset_se), spinbutton, 1, 0, 1, 1);
+  gtk_widget_show (spinbutton);
+
+  gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (offset_tool->offset_se),
+                                _("_X:"), 0, 0, 0.0);
+  gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (offset_tool->offset_se),
+                                _("_Y:"), 1, 0, 0.0);
+
+  gtk_box_pack_start (GTK_BOX (vbox), offset_tool->offset_se, FALSE, FALSE, 0);
+  gtk_widget_show (offset_tool->offset_se);
+
+  gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (offset_tool->offset_se),
+                            GIMP_UNIT_PIXEL);
+
+  g_signal_connect (offset_tool->offset_se, "refval-changed",
+                    G_CALLBACK (gimp_offset_tool_offset_changed),
+                    offset_tool);
+  g_signal_connect (offset_tool->offset_se, "value-changed",
+                    G_CALLBACK (gimp_offset_tool_offset_changed),
+                    offset_tool);
+
+  button = gtk_button_new_with_mnemonic (_("By width/_2, height/2"));
+  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+  gtk_widget_show (button);
+
+  g_signal_connect (button, "clicked",
+                    G_CALLBACK (gimp_offset_tool_half_xy_clicked),
+                    offset_tool);
+
+  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+  gtk_widget_show (hbox);
+
+  button = gtk_button_new_with_mnemonic ("By _width/2");
+  gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+  gtk_widget_show (button);
+
+  g_signal_connect (button, "clicked",
+                    G_CALLBACK (gimp_offset_tool_half_x_clicked),
+                    offset_tool);
+
+  button = gtk_button_new_with_mnemonic ("By _height/2");
+  gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+  gtk_widget_show (button);
+
+  g_signal_connect (button, "clicked",
+                    G_CALLBACK (gimp_offset_tool_half_y_clicked),
+                    offset_tool);
+
+  /*  The edge behavior frame  */
+  frame = gimp_int_radio_group_new (TRUE, _("Edge Behavior"),
+
+                                    G_CALLBACK (gimp_offset_tool_edge_behavior_toggled),
+                                    offset_tool,
+
+                                    GIMP_OFFSET_WRAP_AROUND,
+
+                                    _("W_rap around"),
+                                    GIMP_OFFSET_WRAP_AROUND, NULL,
+
+                                    _("Fill with _background color"),
+                                    GIMP_OFFSET_BACKGROUND, NULL,
+
+                                    _("Make _transparent"),
+                                    GIMP_OFFSET_TRANSPARENT,
+                                    &offset_tool->transparent_radio,
+                                    NULL);
+
+  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
+  gtk_widget_show (frame);
+}
+
+static void
+gimp_offset_tool_config_notify (GimpFilterTool   *filter_tool,
+                                GimpConfig       *config,
+                                const GParamSpec *pspec)
+{
+  gimp_offset_tool_update (GIMP_OFFSET_TOOL (filter_tool));
+
+  GIMP_FILTER_TOOL_CLASS (parent_class)->config_notify (filter_tool,
+                                                        config, pspec);
+}
+
+static void
+gimp_offset_tool_offset_changed (GimpSizeEntry  *se,
+                                 GimpOffsetTool *offset_tool)
+{
+  g_object_set (GIMP_FILTER_TOOL (offset_tool)->config,
+                "x", (gint) gimp_size_entry_get_refval (se, 0),
+                "y", (gint) gimp_size_entry_get_refval (se, 1),
+                NULL);
+}
+
+static void
+gimp_offset_tool_half_xy_clicked (GtkButton      *button,
+                                  GimpOffsetTool *offset_tool)
+{
+  g_object_set (GIMP_FILTER_TOOL (offset_tool)->config,
+                "x", gimp_offset_tool_get_width  (offset_tool) / 2,
+                "y", gimp_offset_tool_get_height (offset_tool) / 2,
+                NULL);
+}
+
+static void
+gimp_offset_tool_half_x_clicked (GtkButton      *button,
+                                 GimpOffsetTool *offset_tool)
+{
+  g_object_set (GIMP_FILTER_TOOL (offset_tool)->config,
+                "x", gimp_offset_tool_get_width (offset_tool) / 2,
+                NULL);
+}
+
+static void
+gimp_offset_tool_half_y_clicked (GtkButton      *button,
+                                 GimpOffsetTool *offset_tool)
+{
+  g_object_set (GIMP_FILTER_TOOL (offset_tool)->config,
+                "y", gimp_offset_tool_get_height (offset_tool) / 2,
+                NULL);
+}
+
+static void
+gimp_offset_tool_edge_behavior_toggled (GtkToggleButton *toggle,
+                                        GimpOffsetTool  *offset_tool)
+{
+  if (gtk_toggle_button_get_active (toggle))
+    {
+      GimpOffsetType type;
+
+      type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (toggle),
+                                                 "gimp-item-data"));
+
+      g_object_set (GIMP_FILTER_TOOL (offset_tool)->config,
+                    "type", type,
+                    NULL);
+    }
+}
+
+static void
+gimp_offset_tool_background_changed (GimpContext    *context,
+                                     const GimpRGB  *color,
+                                     GimpOffsetTool *offset_tool)
+{
+  GimpFilterTool *filter_tool = GIMP_FILTER_TOOL (offset_tool);
+  GimpOffsetType  type;
+
+  g_object_get (filter_tool->config,
+                "type", &type,
+                NULL);
+
+  if (type == GIMP_OFFSET_BACKGROUND)
+    {
+      gegl_node_set (filter_tool->operation,
+                     "context", context,
+                     NULL);
+
+      gimp_drawable_filter_apply (filter_tool->filter, NULL);
+    }
+}
+
+static gint
+gimp_offset_tool_get_width (GimpOffsetTool *offset_tool)
+{
+  GeglRectangle drawable_area;
+  gint          drawable_offset_x;
+  gint          drawable_offset_y;
+
+  if (gimp_filter_tool_get_drawable_area (GIMP_FILTER_TOOL (offset_tool),
+                                          &drawable_offset_x,
+                                          &drawable_offset_y,
+                                          &drawable_area) &&
+      ! gegl_rectangle_is_empty (&drawable_area))
+    {
+      return drawable_area.width;
+    }
+
+  return 0;
+}
+
+static gint
+gimp_offset_tool_get_height (GimpOffsetTool *offset_tool)
+{
+  GeglRectangle drawable_area;
+  gint          drawable_offset_x;
+  gint          drawable_offset_y;
+
+  if (gimp_filter_tool_get_drawable_area (GIMP_FILTER_TOOL (offset_tool),
+                                          &drawable_offset_x,
+                                          &drawable_offset_y,
+                                          &drawable_area) &&
+      ! gegl_rectangle_is_empty (&drawable_area))
+    {
+      return drawable_area.height;
+    }
+
+  return 0;
+}
+
+static void
+gimp_offset_tool_update (GimpOffsetTool *offset_tool)
+{
+  GimpTool       *tool        = GIMP_TOOL (offset_tool);
+  GimpFilterTool *filter_tool = GIMP_FILTER_TOOL (offset_tool);
+  GimpOffsetType  orig_type;
+  gint            orig_x;
+  gint            orig_y;
+  GimpOffsetType  type;
+  gint            x;
+  gint            y;
+  gint            width;
+  gint            height;
+
+  g_object_get (filter_tool->config,
+                "type", &orig_type,
+                "x",    &orig_x,
+                "y",    &orig_y,
+                NULL);
+
+  width  = gimp_offset_tool_get_width  (offset_tool);
+  height = gimp_offset_tool_get_height (offset_tool);
+
+  x = CLAMP (orig_x, -width,  +width);
+  y = CLAMP (orig_y, -height, +height);
+
+  type = orig_type;
+
+  if (tool->drawable                             &&
+      ! gimp_drawable_has_alpha (tool->drawable) &&
+      type == GIMP_OFFSET_TRANSPARENT)
+    {
+      type = GIMP_OFFSET_BACKGROUND;
+    }
+
+  if (x    != orig_x ||
+      y    != orig_y ||
+      type != orig_type)
+    {
+      g_object_set (filter_tool->config,
+                    "type", type,
+                    "x",    x,
+                    "y",    y,
+                    NULL);
+    }
+
+  if (offset_tool->offset_se)
+    {
+      gint width  = gimp_offset_tool_get_width  (offset_tool);
+      gint height = gimp_offset_tool_get_height (offset_tool);
+
+      g_signal_handlers_block_by_func (offset_tool->offset_se,
+                                       gimp_offset_tool_offset_changed,
+                                       offset_tool);
+
+      gimp_size_entry_set_refval_boundaries (
+        GIMP_SIZE_ENTRY (offset_tool->offset_se), 0,
+        -width, +width);
+      gimp_size_entry_set_refval_boundaries (
+        GIMP_SIZE_ENTRY (offset_tool->offset_se), 1,
+        -height, +height);
+
+      gimp_size_entry_set_size (
+        GIMP_SIZE_ENTRY (offset_tool->offset_se), 0,
+        0, width);
+      gimp_size_entry_set_size (
+        GIMP_SIZE_ENTRY (offset_tool->offset_se), 1,
+        0, height);
+
+      gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (offset_tool->offset_se), 0,
+                                  x);
+      gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (offset_tool->offset_se), 1,
+                                  y);
+
+      g_signal_handlers_unblock_by_func (offset_tool->offset_se,
+                                         gimp_offset_tool_offset_changed,
+                                         offset_tool);
+    }
+
+  if (offset_tool->transparent_radio)
+    {
+      gimp_int_radio_group_set_active (
+        GTK_RADIO_BUTTON (offset_tool->transparent_radio),
+        type);
+    }
+}
+
+static void
+gimp_offset_tool_halt (GimpOffsetTool *offset_tool)
+{
+  GimpContext *context = GIMP_CONTEXT (GIMP_TOOL_GET_OPTIONS (offset_tool));
+
+  offset_tool->offset_se         = NULL;
+  offset_tool->transparent_radio = NULL;
+
+  g_signal_handlers_disconnect_by_func (
+    context,
+    gimp_offset_tool_background_changed,
+    offset_tool);
+}
diff --git a/app/tools/gimpoffsettool.h b/app/tools/gimpoffsettool.h
new file mode 100644
index 0000000000..ff651dede3
--- /dev/null
+++ b/app/tools/gimpoffsettool.h
@@ -0,0 +1,63 @@
+/* GIMP - The GNU 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 3 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, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_OFFSET_TOOL_H__
+#define __GIMP_OFFSET_TOOL_H__
+
+
+#include "gimpfiltertool.h"
+
+
+#define GIMP_TYPE_OFFSET_TOOL            (gimp_offset_tool_get_type ())
+#define GIMP_OFFSET_TOOL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_OFFSET_TOOL, 
GimpOffsetTool))
+#define GIMP_OFFSET_TOOL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_OFFSET_TOOL, 
GimpOffsetToolClass))
+#define GIMP_IS_OFFSET_TOOL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_OFFSET_TOOL))
+#define GIMP_IS_OFFSET_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_OFFSET_TOOL))
+#define GIMP_OFFSET_TOOL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_OFFSET_TOOL, 
GimpOffsetToolClass))
+
+
+typedef struct _GimpOffsetTool      GimpOffsetTool;
+typedef struct _GimpOffsetToolClass GimpOffsetToolClass;
+
+struct _GimpOffsetTool
+{
+  GimpFilterTool  parent_instance;
+
+  gboolean        dragging;
+  gdouble         x;
+  gdouble         y;
+  gint            offset_x;
+  gint            offset_y;
+
+  /* dialog */
+  GtkWidget      *offset_se;
+  GtkWidget      *transparent_radio;
+};
+
+struct _GimpOffsetToolClass
+{
+  GimpFilterToolClass  parent_class;
+};
+
+
+void    gimp_offset_tool_register (GimpToolRegisterCallback callback,
+                                   gpointer                 data);
+
+GType   gimp_offset_tool_get_type (void) G_GNUC_CONST;
+
+
+#endif  /*  __GIMP_OFFSET_TOOL_H__  */
diff --git a/app/widgets/gimphelp-ids.h b/app/widgets/gimphelp-ids.h
index 2702c6df2a..a639d646fa 100644
--- a/app/widgets/gimphelp-ids.h
+++ b/app/widgets/gimphelp-ids.h
@@ -318,6 +318,7 @@
 #define GIMP_HELP_TOOL_MOVE                       "gimp-tool-move"
 #define GIMP_HELP_TOOL_MYPAINT_BRUSH              "gimp-tool-mypaint-brush"
 #define GIMP_HELP_TOOL_N_POINT_DEFORMATION        "gimp-tool-n-point-deformation"
+#define GIMP_HELP_TOOL_OFFSET                     "gimp-tool-offset"
 #define GIMP_HELP_TOOL_PATH                       "gimp-tool-path"
 #define GIMP_HELP_TOOL_PAINTBRUSH                 "gimp-tool-paintbrush"
 #define GIMP_HELP_TOOL_PENCIL                     "gimp-tool-pencil"
diff --git a/icons/Color/16/gimp-tool-offset.png b/icons/Color/16/gimp-tool-offset.png
new file mode 100644
index 0000000000..aa0abbc2a7
Binary files /dev/null and b/icons/Color/16/gimp-tool-offset.png differ
diff --git a/icons/Color/24/gimp-tool-offset.png b/icons/Color/24/gimp-tool-offset.png
new file mode 100644
index 0000000000..d4607ac61d
Binary files /dev/null and b/icons/Color/24/gimp-tool-offset.png differ
diff --git a/icons/Color/24/gimp-tool-offset.svg b/icons/Color/24/gimp-tool-offset.svg
new file mode 100644
index 0000000000..237def858e
--- /dev/null
+++ b/icons/Color/24/gimp-tool-offset.svg
@@ -0,0 +1,293 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb";
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:xlink="http://www.w3.org/1999/xlink";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   width="24"
+   height="24"
+   viewBox="0 0 24 24"
+   id="svg30571"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="gimp-tool-offset.svg"
+   inkscape:export-xdpi="96"
+   inkscape:export-ydpi="96">
+  <title
+     id="title5690">GIMP Offset Tool</title>
+  <defs
+     id="defs30573">
+    <linearGradient
+       id="linearGradient4989-64">
+      <stop
+         id="stop4991-7"
+         offset="0.0000000"
+         style="stop-color:#d3e9ff;stop-opacity:1.0000000;" />
+      <stop
+         id="stop4993-6"
+         offset="0.20796148"
+         style="stop-color:#d3e9ff;stop-opacity:1.0000000;" />
+      <stop
+         id="stop4995-9"
+         offset="0.8170042"
+         style="stop-color:#4074ae;stop-opacity:1.0000000;" />
+      <stop
+         id="stop4997-4"
+         offset="1.0000000"
+         style="stop-color:#36486c;stop-opacity:1.0000000;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient6951-5">
+      <stop
+         id="stop6961-6"
+         stop-color="#ee8719" />
+      <stop
+         offset="1"
+         id="stop6955-9"
+         stop-color="#e07c12"
+         stop-opacity="0" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="matrix(0.01502614,0,0,0.01468232,2.9686133,1037.3257)"
+       id="linearGradient6057"
+       gradientUnits="userSpaceOnUse"
+       x2="320.70001"
+       x1="231.55"
+       osb:paint="gradient">
+      <stop
+         id="stop6053"
+         stop-color="#a11f7c" />
+      <stop
+         id="stop6055"
+         offset="1"
+         stop-color="#541f31"
+         stop-opacity="0.984" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3204-1"
+       id="linearGradient8313"
+       x1="191.02673"
+       y1="320.22839"
+       x2="173.83766"
+       y2="337.29449"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.5438992,0,0,1.5438992,-276.96693,541.42922)" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient3204-1">
+      <stop
+         id="stop3206" />
+      <stop
+         offset="1"
+         id="stop3208"
+         stop-opacity="0" />
+    </linearGradient>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="29.541667"
+     inkscape:cx="12"
+     inkscape:cy="12"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     units="px"
+     inkscape:snap-page="true"
+     inkscape:snap-bbox="true"
+     inkscape:bbox-paths="true"
+     inkscape:bbox-nodes="true"
+     inkscape:snap-bbox-edge-midpoints="true"
+     inkscape:snap-bbox-midpoints="true"
+     inkscape:object-paths="true"
+     inkscape:snap-intersection-paths="true"
+     inkscape:object-nodes="true"
+     inkscape:snap-smooth-nodes="true"
+     inkscape:snap-midpoints="true"
+     inkscape:snap-object-midpoints="true"
+     inkscape:snap-center="true"
+     inkscape:snap-text-baseline="true"
+     showborder="true"
+     inkscape:window-width="1535"
+     inkscape:window-height="876"
+     inkscape:window-x="65"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1"
+     inkscape:snap-global="false"
+     showguides="false">
+    <inkscape:grid
+       type="xygrid"
+       id="grid4369" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata30576">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title>GIMP Offset Tool</dc:title>
+        <dc:creator>
+          <cc:Agent>
+            <dc:title>Klaus Staedtler</dc:title>
+          </cc:Agent>
+        </dc:creator>
+        <cc:license
+           rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/"; />
+      </cc:Work>
+      <cc:License
+         rdf:about="http://creativecommons.org/licenses/by-sa/4.0/";>
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#Reproduction"; />
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#Distribution"; />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#Notice"; />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#Attribution"; />
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#DerivativeWorks"; />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#ShareAlike"; />
+      </cc:License>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-1028.3622)">
+    <g
+       id="gimp-tool-offset">
+      <g
+         inkscape:transform-center-y="0.025736985"
+         inkscape:transform-center-x="-4.7441149"
+         id="gimp-grid"
+         transform="matrix(1.4722143,0,0,1.4723149,0.22242684,1028.5839)">
+        <rect
+           
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#d3d7cf;fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:0.69205183;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+           id="rect1908-2"
+           width="15.610076"
+           height="15.608502"
+           x="0.19494273"
+           y="0.19574897"
+           rx="0.48743445"
+           ry="0.48929465" />
+      </g>
+      <g
+         style="stroke-width:1.34783971"
+         transform="matrix(0.74197001,0,0,0.74188598,3.0967936,268.53249)"
+         id="g4592">
+        <path
+           d="m 11.999996,1028.7375 -5.2499975,4.1247 h 3.7499985 v 6 H 4.5000897 l -1.801e-4,-3.75 
-4.12459101,5.25 4.12459101,5.052 v -3.552 h 6.0000874 v 6 H 6.7499985 l 5.2499975,4.1247 5.249998,-4.1247 h 
-3.749999 v -6 h 5.999998 v 3.948 l 4.124681,-5.448 -4.124681,-5.25 v 3.75 h -5.999998 v -6 h 3.749999 z"
+           id="gimp-tool-move"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="ccccccccccccccccccccccccc"
+           stroke-miterlimit="10"
+           
style="color:#000000;display:inline;fill:#3465a4;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8313);stroke-width:1.01177597;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none"
+           inkscape:export-xdpi="123.75011"
+           inkscape:export-ydpi="123.75011" />
+        <rect
+           
style="opacity:0.33000004;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.44852567;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="rect3947"
+           width="21.000269"
+           height="0.74999964"
+           x="1.500001"
+           y="1039.9872" />
+        <rect
+           
style="opacity:0.33000004;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.44852567;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="rect3947-0"
+           width="21.000269"
+           height="0.74999964"
+           x="1029.8619"
+           y="-12.374996"
+           transform="rotate(90)" />
+        <path
+           sodipodi:type="star"
+           
style="opacity:0.5;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.69567943;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="path3964"
+           sodipodi:sides="3"
+           sodipodi:cx="-8.0524263"
+           sodipodi:cy="1030.9637"
+           sodipodi:r1="1.2900716"
+           sodipodi:r2="0.6450358"
+           sodipodi:arg1="1.2298174"
+           sodipodi:arg2="2.2770149"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m -7.6210137,1032.1795 -1.700032,-1.45 2.1058261,-0.7473 z"
+           inkscape:transform-center-x="0.013957276"
+           inkscape:transform-center-y="-0.15930067"
+           transform="matrix(1.2979666,-0.48616464,1.064361,0.59286793,-1074.8903,415.44856)" />
+        <path
+           sodipodi:type="star"
+           
style="opacity:0.5;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.69567943;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="path3964-3"
+           sodipodi:sides="3"
+           sodipodi:cx="-8.0524263"
+           sodipodi:cy="1030.9637"
+           sodipodi:r1="1.2900716"
+           sodipodi:r2="0.6450358"
+           sodipodi:arg1="1.2298174"
+           sodipodi:arg2="2.2770149"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m -7.6210137,1032.1795 -1.700032,-1.45 2.1058261,-0.7473 z"
+           inkscape:transform-center-x="0.013957276"
+           inkscape:transform-center-y="0.15932022"
+           transform="matrix(1.2979666,0.48616464,1.064361,-0.59286793,-1074.8695,1665.3571)" />
+        <path
+           sodipodi:type="star"
+           
style="opacity:0.5;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.69567943;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="path3964-3-2"
+           sodipodi:sides="3"
+           sodipodi:cx="-8.0524263"
+           sodipodi:cy="1030.9637"
+           sodipodi:r1="1.2900716"
+           sodipodi:r2="0.6450358"
+           sodipodi:arg1="1.2298174"
+           sodipodi:arg2="2.2770149"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m -7.6210137,1032.1795 -1.700032,-1.45 2.1058261,-0.7473 z"
+           inkscape:transform-center-x="-0.15932047"
+           inkscape:transform-center-y="0.013928413"
+           transform="matrix(0.48616464,-1.2979666,-0.59286793,-1.064361,636.96143,2127.3281)" />
+        <path
+           sodipodi:type="star"
+           
style="opacity:0.5;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.69567943;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="path3964-3-2-8"
+           sodipodi:sides="3"
+           sodipodi:cx="-8.0524263"
+           sodipodi:cy="1030.9637"
+           sodipodi:r1="1.2900716"
+           sodipodi:r2="0.6450358"
+           sodipodi:arg1="1.2298174"
+           sodipodi:arg2="2.2770149"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m -7.6210137,1032.1795 -1.700032,-1.45 2.1058261,-0.7473 z"
+           inkscape:transform-center-x="0.15932002"
+           inkscape:transform-center-y="0.013928413"
+           transform="matrix(-0.48616464,-1.2979666,0.59286793,-1.064361,-612.94767,2127.2153)" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/icons/Color/color-scalable.svg b/icons/Color/color-scalable.svg
index 27efde655d..88d2677380 100644
--- a/icons/Color/color-scalable.svg
+++ b/icons/Color/color-scalable.svg
@@ -13,7 +13,7 @@
    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
    viewBox="0 0 1411.4984 384.2294"
    sodipodi:docname="color-scalable.svg"
-   inkscape:version="0.92.3 (2405546, 2018-03-11)"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
    id="svg"
    height="384.2294"
    width="1411.4984"
@@ -61,8 +61,8 @@
      inkscape:window-maximized="1"
      inkscape:window-y="24"
      inkscape:window-x="65"
-     inkscape:cy="118.27566"
-     inkscape:cx="616.06499"
+     inkscape:cy="114.22313"
+     inkscape:cx="593.4191"
      inkscape:zoom="1"
      showgrid="false"
      id="namedview88"
@@ -18359,6 +18359,26 @@
          offset="1"
          id="stop844" />
     </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient8437"
+       id="linearGradient27989"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0292666,0,0,1.0292666,-184.64471,711.74006)"
+       x1="191.02673"
+       y1="320.22839"
+       x2="173.83766"
+       y2="337.29449" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient8437"
+       id="linearGradient28650"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.5438992,0,0,1.5438992,-276.96693,541.42922)"
+       x1="191.02673"
+       y1="320.22839"
+       x2="173.83766"
+       y2="337.29449" />
   </defs>
   <g
      inkscape:groupmode="layer"
@@ -56028,6 +56048,246 @@
          id="rect18113"
          
style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 />
     </g>
+    <g
+       transform="translate(-351.96097,-902.47774)"
+       id="gimp-tool-offset">
+      <g
+         inkscape:transform-center-y="0.025736985"
+         inkscape:transform-center-x="-4.7441149"
+         id="gimp-grid-9"
+         transform="matrix(0.96327079,0,0,0.96336725,0.2938523,1036.6552)">
+        <rect
+           
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#d3d7cf;fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:0.99999905;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+           id="rect1908-2"
+           width="15.610076"
+           height="15.608502"
+           x="0.19494273"
+           y="0.19574897"
+           rx="0.48743445"
+           ry="0.48929465" />
+      </g>
+      <g
+         style="stroke-width:1.34784341"
+         transform="matrix(0.74181427,0,0,0.74203773,2.0654856,269.40607)"
+         id="g3960">
+        <path
+           d="m 8,1036.6124 -3.5,2.7498 H 7 v 4 H 3.0000601 l -1.201e-4,-2.5 -2.7497286,3.5 2.7497286,3.368 
v -2.368 H 7 v 4 H 4.5 l 3.5,2.7498 3.5,-2.7498 H 9 v -4 h 4 v 2.632 l 2.749789,-3.632 -2.749789,-3.5 v 2.5 H 
9 v -4 h 2.5 z"
+           id="gimp-tool-move-1"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="ccccccccccccccccccccccccc"
+           stroke-miterlimit="10"
+           
style="color:#000000;display:inline;fill:#3465a4;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient27989);stroke-width:0.67451942;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none"
+           inkscape:export-xdpi="123.75011"
+           inkscape:export-ydpi="123.75011" />
+        <rect
+           
style="opacity:0.33000004;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:1.63235557;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="rect3947-2"
+           width="14.000186"
+           height="0.5"
+           x="1"
+           y="1044.1122" />
+        <rect
+           
style="opacity:0.33000004;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:1.63235557;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="rect3947-0-7"
+           width="14.000186"
+           height="0.5"
+           x="1037.3621"
+           y="-8.25"
+           transform="rotate(90)" />
+        <path
+           sodipodi:type="star"
+           
style="opacity:0.5;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.69568682;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="path3964-09"
+           sodipodi:sides="3"
+           sodipodi:cx="-8.0524263"
+           sodipodi:cy="1030.9637"
+           sodipodi:r1="1.2900716"
+           sodipodi:r2="0.6450358"
+           sodipodi:arg1="1.2298174"
+           sodipodi:arg2="2.2770149"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m -7.6210137,1032.1795 -1.700032,-1.45 2.1058261,-0.7473 z"
+           inkscape:transform-center-x="0.013957276"
+           inkscape:transform-center-y="-0.15930067"
+           transform="matrix(0.86531148,-0.32410991,0.7095743,0.39524547,-716.63553,627.75291)" />
+        <path
+           sodipodi:type="star"
+           
style="opacity:0.5;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.69568682;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="path3964-3-3"
+           sodipodi:sides="3"
+           sodipodi:cx="-8.0524263"
+           sodipodi:cy="1030.9637"
+           sodipodi:r1="1.2900716"
+           sodipodi:r2="0.6450358"
+           sodipodi:arg1="1.2298174"
+           sodipodi:arg2="2.2770149"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m -7.6210137,1032.1795 -1.700032,-1.45 2.1058261,-0.7473 z"
+           inkscape:transform-center-x="0.013957276"
+           inkscape:transform-center-y="0.15932022"
+           transform="matrix(0.86531148,0.32410991,0.7095743,-0.39524547,-716.62169,1460.984)" />
+        <path
+           sodipodi:type="star"
+           
style="opacity:0.5;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.69568682;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="path3964-3-2-6"
+           sodipodi:sides="3"
+           sodipodi:cx="-8.0524263"
+           sodipodi:cy="1030.9637"
+           sodipodi:r1="1.2900716"
+           sodipodi:r2="0.6450358"
+           sodipodi:arg1="1.2298174"
+           sodipodi:arg2="2.2770149"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m -7.6210137,1032.1795 -1.700032,-1.45 2.1058261,-0.7473 z"
+           inkscape:transform-center-x="-0.15932047"
+           inkscape:transform-center-y="0.013928413"
+           transform="matrix(0.32410991,-0.86531148,-0.39524547,-0.7095743,424.64115,1769.0065)" />
+        <path
+           sodipodi:type="star"
+           
style="opacity:0.5;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.69568682;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="path3964-3-2-8-0"
+           sodipodi:sides="3"
+           sodipodi:cx="-8.0524263"
+           sodipodi:cy="1030.9637"
+           sodipodi:r1="1.2900716"
+           sodipodi:r2="0.6450358"
+           sodipodi:arg1="1.2298174"
+           sodipodi:arg2="2.2770149"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m -7.6210137,1032.1795 -1.700032,-1.45 2.1058261,-0.7473 z"
+           inkscape:transform-center-x="0.15932002"
+           inkscape:transform-center-y="0.013928413"
+           transform="matrix(-0.32410991,-0.86531148,0.39524547,-0.7095743,-408.63197,1768.9313)" />
+      </g>
+    </g>
+    <g
+       transform="translate(-160.06298,-902.30203)"
+       id="gimp-tool-offset-6">
+      <g
+         inkscape:transform-center-y="0.025736985"
+         inkscape:transform-center-x="-4.7441149"
+         id="gimp-grid-18"
+         transform="matrix(1.4722143,0,0,1.4723149,0.22242684,1028.5839)">
+        <rect
+           
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#d3d7cf;fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:0.69205183;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+           id="rect1908-2-7"
+           width="15.610076"
+           height="15.608502"
+           x="0.19494273"
+           y="0.19574897"
+           rx="0.48743445"
+           ry="0.48929465" />
+      </g>
+      <g
+         style="stroke-width:1.34783971"
+         transform="matrix(0.74197001,0,0,0.74188598,3.0967936,268.53249)"
+         id="g4592">
+        <path
+           d="m 11.999996,1028.7375 -5.2499975,4.1247 h 3.7499985 v 6 H 4.5000897 l -1.801e-4,-3.75 
-4.12459101,5.25 4.12459101,5.052 v -3.552 h 6.0000874 v 6 H 6.7499985 l 5.2499975,4.1247 5.249998,-4.1247 h 
-3.749999 v -6 h 5.999998 v 3.948 l 4.124681,-5.448 -4.124681,-5.25 v 3.75 h -5.999998 v -6 h 3.749999 z"
+           id="gimp-tool-move-92"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="ccccccccccccccccccccccccc"
+           stroke-miterlimit="10"
+           
style="color:#000000;display:inline;fill:#3465a4;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient28650);stroke-width:1.01177597;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none"
+           inkscape:export-xdpi="123.75011"
+           inkscape:export-ydpi="123.75011" />
+        <rect
+           
style="opacity:0.33000004;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.44852567;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="rect3947-02"
+           width="21.000269"
+           height="0.74999964"
+           x="1.500001"
+           y="1039.9872" />
+        <rect
+           
style="opacity:0.33000004;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.44852567;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="rect3947-0-3"
+           width="21.000269"
+           height="0.74999964"
+           x="1029.8619"
+           y="-12.374996"
+           transform="rotate(90)" />
+        <path
+           sodipodi:type="star"
+           
style="opacity:0.5;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.69567943;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="path3964-7"
+           sodipodi:sides="3"
+           sodipodi:cx="-8.0524263"
+           sodipodi:cy="1030.9637"
+           sodipodi:r1="1.2900716"
+           sodipodi:r2="0.6450358"
+           sodipodi:arg1="1.2298174"
+           sodipodi:arg2="2.2770149"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m -7.6210137,1032.1795 -1.700032,-1.45 2.1058261,-0.7473 z"
+           inkscape:transform-center-x="0.013957276"
+           inkscape:transform-center-y="-0.15930067"
+           transform="matrix(1.2979666,-0.48616464,1.064361,0.59286793,-1074.8903,415.44856)" />
+        <path
+           sodipodi:type="star"
+           
style="opacity:0.5;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.69567943;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="path3964-3-5"
+           sodipodi:sides="3"
+           sodipodi:cx="-8.0524263"
+           sodipodi:cy="1030.9637"
+           sodipodi:r1="1.2900716"
+           sodipodi:r2="0.6450358"
+           sodipodi:arg1="1.2298174"
+           sodipodi:arg2="2.2770149"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m -7.6210137,1032.1795 -1.700032,-1.45 2.1058261,-0.7473 z"
+           inkscape:transform-center-x="0.013957276"
+           inkscape:transform-center-y="0.15932022"
+           transform="matrix(1.2979666,0.48616464,1.064361,-0.59286793,-1074.8695,1665.3571)" />
+        <path
+           sodipodi:type="star"
+           
style="opacity:0.5;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.69567943;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="path3964-3-2-9"
+           sodipodi:sides="3"
+           sodipodi:cx="-8.0524263"
+           sodipodi:cy="1030.9637"
+           sodipodi:r1="1.2900716"
+           sodipodi:r2="0.6450358"
+           sodipodi:arg1="1.2298174"
+           sodipodi:arg2="2.2770149"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m -7.6210137,1032.1795 -1.700032,-1.45 2.1058261,-0.7473 z"
+           inkscape:transform-center-x="-0.15932047"
+           inkscape:transform-center-y="0.013928413"
+           transform="matrix(0.48616464,-1.2979666,-0.59286793,-1.064361,636.96143,2127.3281)" />
+        <path
+           sodipodi:type="star"
+           
style="opacity:0.5;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.69567943;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="path3964-3-2-8-2"
+           sodipodi:sides="3"
+           sodipodi:cx="-8.0524263"
+           sodipodi:cy="1030.9637"
+           sodipodi:r1="1.2900716"
+           sodipodi:r2="0.6450358"
+           sodipodi:arg1="1.2298174"
+           sodipodi:arg2="2.2770149"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m -7.6210137,1032.1795 -1.700032,-1.45 2.1058261,-0.7473 z"
+           inkscape:transform-center-x="0.15932002"
+           inkscape:transform-center-y="0.013928413"
+           transform="matrix(-0.48616464,-1.2979666,0.59286793,-1.064361,-612.94767,2127.2153)" />
+      </g>
+    </g>
   </g>
   <g
      inkscape:groupmode="layer"
diff --git a/icons/Color/icon-list.mk b/icons/Color/icon-list.mk
index 8708736f94..548e30a24f 100644
--- a/icons/Color/icon-list.mk
+++ b/icons/Color/icon-list.mk
@@ -299,6 +299,7 @@ scalable_images = \
        scalable/gimp-tool-move.svg                             \
        scalable/gimp-tool-mypaint-brush.svg                    \
        scalable/gimp-tool-n-point-deformation.svg              \
+       scalable/gimp-tool-offset.svg                           \
        scalable/gimp-tool-options.svg                          \
        scalable/gimp-tool-paintbrush.svg                       \
        scalable/gimp-tool-path.svg                             \
@@ -474,6 +475,7 @@ vector24_images = \
        24/gimp-tool-mypaint-brush.svg                          \
        24/gimp-tool-measure.svg                                \
        24/gimp-tool-n-point-deformation.svg                    \
+       24/gimp-tool-offset.svg                                 \
        24/gimp-tool-options.svg                                \
        24/gimp-tool-paintbrush.svg                             \
        24/gimp-tool-path.svg                                   \
@@ -763,6 +765,7 @@ icons16_images = \
        16/gimp-tool-move.png                                   \
        16/gimp-tool-mypaint-brush.png                          \
        16/gimp-tool-n-point-deformation.png                    \
+       16/gimp-tool-offset.png                                 \
        16/gimp-tool-options.png                                \
        16/gimp-tool-paintbrush.png                             \
        16/gimp-tool-path.png                                   \
@@ -974,6 +977,7 @@ icons24_images = \
        24/gimp-tool-move.png                                   \
        24/gimp-tool-mypaint-brush.png                          \
        24/gimp-tool-n-point-deformation.png                    \
+       24/gimp-tool-offset.png                                 \
        24/gimp-tool-paintbrush.png                             \
        24/gimp-tool-path.png                                   \
        24/gimp-tool-pencil.png                                 \
diff --git a/icons/Color/scalable/gimp-tool-offset.svg b/icons/Color/scalable/gimp-tool-offset.svg
new file mode 100644
index 0000000000..4619d72e24
--- /dev/null
+++ b/icons/Color/scalable/gimp-tool-offset.svg
@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:xlink="http://www.w3.org/1999/xlink";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   width="16"
+   height="16"
+   viewBox="0 0 16 16"
+   id="svg30571"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="gimp-tool-offset.svg"
+   inkscape:export-xdpi="98.181816"
+   inkscape:export-ydpi="98.181816">
+  <title
+     id="title7666">GIMP Offset Tool</title>
+  <defs
+     id="defs30573">
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3204-1"
+       id="linearGradient8313"
+       x1="191.02673"
+       y1="320.22839"
+       x2="173.83766"
+       y2="337.29449"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0292666,0,0,1.0292666,-184.64471,711.74006)" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient3204-1">
+      <stop
+         id="stop3206" />
+      <stop
+         offset="1"
+         id="stop3208"
+         stop-opacity="0" />
+    </linearGradient>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="44.3125"
+     inkscape:cx="8"
+     inkscape:cy="8"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     units="px"
+     inkscape:snap-page="true"
+     inkscape:snap-bbox="true"
+     inkscape:bbox-paths="true"
+     inkscape:bbox-nodes="true"
+     inkscape:snap-bbox-edge-midpoints="true"
+     inkscape:snap-bbox-midpoints="true"
+     inkscape:object-paths="true"
+     inkscape:snap-intersection-paths="true"
+     inkscape:object-nodes="true"
+     inkscape:snap-smooth-nodes="true"
+     inkscape:snap-midpoints="true"
+     inkscape:snap-object-midpoints="true"
+     inkscape:snap-center="true"
+     inkscape:snap-text-baseline="true"
+     showborder="false"
+     inkscape:window-width="1535"
+     inkscape:window-height="876"
+     inkscape:window-x="65"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1"
+     inkscape:snap-global="false"
+     showguides="false">
+    <inkscape:grid
+       type="xygrid"
+       id="grid4011" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata30576">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title>GIMP Offset Tool</dc:title>
+        <dc:creator>
+          <cc:Agent>
+            <dc:title>Klaus Staedtler</dc:title>
+          </cc:Agent>
+        </dc:creator>
+        <cc:license
+           rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/"; />
+      </cc:Work>
+      <cc:License
+         rdf:about="http://creativecommons.org/licenses/by-sa/4.0/";>
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#Reproduction"; />
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#Distribution"; />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#Notice"; />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#Attribution"; />
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#DerivativeWorks"; />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#ShareAlike"; />
+      </cc:License>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-1036.3622)">
+    <g
+       id="gimp-tool-offset">
+      <g
+         inkscape:transform-center-y="0.025736985"
+         inkscape:transform-center-x="-4.7441149"
+         id="gimp-grid"
+         transform="matrix(0.96327079,0,0,0.96336725,0.2938523,1036.6552)">
+        <rect
+           
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#d3d7cf;fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:0.99999905;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+           id="rect1908-2"
+           width="15.610076"
+           height="15.608502"
+           x="0.19494273"
+           y="0.19574897"
+           rx="0.48743445"
+           ry="0.48929465" />
+      </g>
+      <g
+         style="stroke-width:1.34784341"
+         transform="matrix(0.74181427,0,0,0.74203773,2.0654856,269.40607)"
+         id="g3960">
+        <path
+           d="m 8,1036.6124 -3.5,2.7498 H 7 v 4 H 3.0000601 l -1.201e-4,-2.5 -2.7497286,3.5 2.7497286,3.368 
v -2.368 H 7 v 4 H 4.5 l 3.5,2.7498 3.5,-2.7498 H 9 v -4 h 4 v 2.632 l 2.749789,-3.632 -2.749789,-3.5 v 2.5 H 
9 v -4 h 2.5 z"
+           id="gimp-tool-move"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="ccccccccccccccccccccccccc"
+           stroke-miterlimit="10"
+           
style="color:#000000;display:inline;fill:#3465a4;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8313);stroke-width:0.67451942;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none"
+           inkscape:export-xdpi="123.75011"
+           inkscape:export-ydpi="123.75011" />
+        <rect
+           
style="opacity:0.33000004;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:1.63235557;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="rect3947"
+           width="14.000186"
+           height="0.5"
+           x="1"
+           y="1044.1122" />
+        <rect
+           
style="opacity:0.33000004;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:1.63235557;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="rect3947-0"
+           width="14.000186"
+           height="0.5"
+           x="1037.3621"
+           y="-8.25"
+           transform="rotate(90)" />
+        <path
+           sodipodi:type="star"
+           
style="opacity:0.5;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.69568682;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="path3964"
+           sodipodi:sides="3"
+           sodipodi:cx="-8.0524263"
+           sodipodi:cy="1030.9637"
+           sodipodi:r1="1.2900716"
+           sodipodi:r2="0.6450358"
+           sodipodi:arg1="1.2298174"
+           sodipodi:arg2="2.2770149"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m -7.6210137,1032.1795 -1.700032,-1.45 2.1058261,-0.7473 z"
+           inkscape:transform-center-x="0.013957276"
+           inkscape:transform-center-y="-0.15930067"
+           transform="matrix(0.86531148,-0.32410991,0.7095743,0.39524547,-716.63553,627.75291)" />
+        <path
+           sodipodi:type="star"
+           
style="opacity:0.5;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.69568682;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="path3964-3"
+           sodipodi:sides="3"
+           sodipodi:cx="-8.0524263"
+           sodipodi:cy="1030.9637"
+           sodipodi:r1="1.2900716"
+           sodipodi:r2="0.6450358"
+           sodipodi:arg1="1.2298174"
+           sodipodi:arg2="2.2770149"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m -7.6210137,1032.1795 -1.700032,-1.45 2.1058261,-0.7473 z"
+           inkscape:transform-center-x="0.013957276"
+           inkscape:transform-center-y="0.15932022"
+           transform="matrix(0.86531148,0.32410991,0.7095743,-0.39524547,-716.62169,1460.984)" />
+        <path
+           sodipodi:type="star"
+           
style="opacity:0.5;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.69568682;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="path3964-3-2"
+           sodipodi:sides="3"
+           sodipodi:cx="-8.0524263"
+           sodipodi:cy="1030.9637"
+           sodipodi:r1="1.2900716"
+           sodipodi:r2="0.6450358"
+           sodipodi:arg1="1.2298174"
+           sodipodi:arg2="2.2770149"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m -7.6210137,1032.1795 -1.700032,-1.45 2.1058261,-0.7473 z"
+           inkscape:transform-center-x="-0.15932047"
+           inkscape:transform-center-y="0.013928413"
+           transform="matrix(0.32410991,-0.86531148,-0.39524547,-0.7095743,424.64115,1769.0065)" />
+        <path
+           sodipodi:type="star"
+           
style="opacity:0.5;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:2.69568682;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke
 fill markers"
+           id="path3964-3-2-8"
+           sodipodi:sides="3"
+           sodipodi:cx="-8.0524263"
+           sodipodi:cy="1030.9637"
+           sodipodi:r1="1.2900716"
+           sodipodi:r2="0.6450358"
+           sodipodi:arg1="1.2298174"
+           sodipodi:arg2="2.2770149"
+           inkscape:flatsided="true"
+           inkscape:rounded="0"
+           inkscape:randomized="0"
+           d="m -7.6210137,1032.1795 -1.700032,-1.45 2.1058261,-0.7473 z"
+           inkscape:transform-center-x="0.15932002"
+           inkscape:transform-center-y="0.013928413"
+           transform="matrix(-0.32410991,-0.86531148,0.39524547,-0.7095743,-408.63197,1768.9313)" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/icons/Symbolic/16/gimp-tool-offset.png b/icons/Symbolic/16/gimp-tool-offset.png
new file mode 100644
index 0000000000..dc98e1472a
Binary files /dev/null and b/icons/Symbolic/16/gimp-tool-offset.png differ
diff --git a/icons/Symbolic/24/gimp-tool-offset.png b/icons/Symbolic/24/gimp-tool-offset.png
new file mode 100644
index 0000000000..09ac72a782
Binary files /dev/null and b/icons/Symbolic/24/gimp-tool-offset.png differ
diff --git a/icons/Symbolic/24/gimp-tool-offset.svg b/icons/Symbolic/24/gimp-tool-offset.svg
new file mode 100644
index 0000000000..37b77fb7f4
--- /dev/null
+++ b/icons/Symbolic/24/gimp-tool-offset.svg
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb";
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:xlink="http://www.w3.org/1999/xlink";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   width="24"
+   height="24"
+   viewBox="0 0 24 24"
+   id="svg30571"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="gimp-tool-offset.svg"
+   inkscape:export-xdpi="96"
+   inkscape:export-ydpi="96">
+  <title
+     id="title4296">GIMP Offset Tool</title>
+  <defs
+     id="defs30573">
+    <linearGradient
+       id="linearGradient19282-4"
+       osb:paint="solid"
+       gradientTransform="matrix(0.34682586,0,0,0.30620888,-482.61525,330.965)">
+      <stop
+         style="stop-color:#bebebe;stop-opacity:1;"
+         offset="0"
+         id="stop19284-0" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient19282-4"
+       id="linearGradient9850"
+       x1="-139"
+       y1="68"
+       x2="-125"
+       y2="68"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.5714285,0,0,1.5714285,219.42856,933.50501)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient19282-4"
+       id="linearGradient7060"
+       x1="295.70312"
+       y1="305.36914"
+       x2="311.70312"
+       y2="305.36914"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="24.375"
+     inkscape:cx="12"
+     inkscape:cy="12.053195"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     units="px"
+     inkscape:snap-page="true"
+     inkscape:snap-bbox="true"
+     inkscape:bbox-paths="true"
+     inkscape:bbox-nodes="true"
+     inkscape:snap-bbox-edge-midpoints="true"
+     inkscape:snap-bbox-midpoints="true"
+     inkscape:object-paths="true"
+     inkscape:snap-intersection-paths="true"
+     inkscape:object-nodes="true"
+     inkscape:snap-smooth-nodes="true"
+     inkscape:snap-midpoints="true"
+     inkscape:snap-object-midpoints="true"
+     inkscape:snap-center="true"
+     inkscape:snap-text-baseline="true"
+     showborder="true"
+     inkscape:window-width="1535"
+     inkscape:window-height="876"
+     inkscape:window-x="65"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1"
+     inkscape:snap-global="false"
+     showguides="false">
+    <inkscape:grid
+       type="xygrid"
+       id="grid4369" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata30576">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title>GIMP Offset Tool</dc:title>
+        <dc:creator>
+          <cc:Agent>
+            <dc:title>Klaus Staedtler</dc:title>
+          </cc:Agent>
+        </dc:creator>
+        <cc:license
+           rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/"; />
+      </cc:Work>
+      <cc:License
+         rdf:about="http://creativecommons.org/licenses/by-sa/4.0/";>
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#Reproduction"; />
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#Distribution"; />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#Notice"; />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#Attribution"; />
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#DerivativeWorks"; />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#ShareAlike"; />
+      </cc:License>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-1028.3622)">
+    <g
+       id="gimp-tool-offset">
+      <rect
+         y="1029.8622"
+         x="1.5"
+         height="21"
+         width="21"
+         id="rect3623"
+         
style="fill:none;fill-rule:evenodd;stroke:#bebebe;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 />
+      <g
+         inkscape:export-ydpi="123.75"
+         inkscape:export-xdpi="123.75"
+         transform="matrix(0.9999675,0,0,0.9999675,-96.996396,835.36912)"
+         inkscape:label="gimp-tool-move"
+         id="gimp-tool-move"
+         style="display:inline;stroke-width:1.50000012">
+        <path
+           sodipodi:nodetypes="ccccccccccccccccccccccccc"
+           inkscape:connector-curvature="0"
+           id="path74740"
+           transform="translate(-194.70344,-100.37001)"
+           d="m 303.70338,297.3695 -3.33336,2.66678 h 2.66667 v 4.67756 c -1.34341,-0.0101 -3.32302,-0.0211 
-4.66682,-0.0293 v -2.64822 l -2.66675,3.33344 2.66675,3.33344 v -2.66675 c 1.34376,-9e-5 3.32305,-0.003 
4.66682,0 0,1.5556 0,3.11121 0,4.66681 h -2.66683 l 3.33352,2.66676 3.33344,-2.66676 h -2.66675 c 0,-1.5556 
0,-3.11121 0,-4.66681 1.33334,9e-4 3.33349,0.004 4.66681,0 v 2.66675 l 2.66676,-3.33344 -2.66676,-3.33344 v 
2.65018 c -1.33322,0.0235 -3.33298,0.0388 -4.66681,0.0351 v -4.68537 h 2.66675 z"
+           style="fill:url(#linearGradient7060);fill-opacity:1;stroke:none;stroke-width:1.50000012" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/icons/Symbolic/scalable/gimp-tool-offset.svg b/icons/Symbolic/scalable/gimp-tool-offset.svg
new file mode 100644
index 0000000000..79391f735d
--- /dev/null
+++ b/icons/Symbolic/scalable/gimp-tool-offset.svg
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb";
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:xlink="http://www.w3.org/1999/xlink";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   viewBox="0 0 16.000518 16.000875"
+   id="svg7384"
+   height="16.000875"
+   width="16.000519"
+   version="1.1"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="gimp-tool-offset.svg">
+  <title
+     id="title8375">GIMP Offset Tool</title>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1535"
+     inkscape:window-height="876"
+     id="namedview1507"
+     showgrid="false"
+     inkscape:zoom="44.310075"
+     inkscape:cx="8.0002594"
+     inkscape:cy="8.0004377"
+     inkscape:window-x="65"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg7384" />
+  <metadata
+     id="metadata90">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title>GIMP Offset Tool</dc:title>
+        <dc:contributor>
+          <cc:Agent>
+            <dc:title>Barbara Muraus, Jakub Steiner, Klaus Staedtler</dc:title>
+          </cc:Agent>
+        </dc:contributor>
+        <dc:description>Images originally created as the &quot;Art Libre&quot; icon set. Extended and 
adopted for GIMP</dc:description>
+        <cc:license
+           rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/"; />
+      </cc:Work>
+      <cc:License
+         rdf:about="http://creativecommons.org/licenses/by-sa/4.0/";>
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#Reproduction"; />
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#Distribution"; />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#Notice"; />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#Attribution"; />
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#DerivativeWorks"; />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#ShareAlike"; />
+      </cc:License>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs7386">
+    <linearGradient
+       osb:paint="solid"
+       id="linearGradient8074">
+      <stop
+         id="stop8072"
+         offset="0"
+         style="stop-color:#be00be;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       osb:paint="solid"
+       id="linearGradient7561">
+      <stop
+         id="stop7558"
+         offset="0"
+         style="stop-color:#a5a5a5;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       osb:paint="solid"
+       id="linearGradient7548">
+      <stop
+         id="stop7546"
+         offset="0"
+         style="stop-color:#ebebeb;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       osb:paint="solid"
+       id="linearGradient7542">
+      <stop
+         id="stop7538"
+         offset="0"
+         style="stop-color:#c9c9c9;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="matrix(0,-735328.32,170712.69,0,2464326300,577972450)"
+       osb:paint="solid"
+       id="linearGradient19282">
+      <stop
+         id="stop19284"
+         offset="0"
+         style="stop-color:#b4b4b4;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="matrix(0.34682586,0,0,0.30620888,-53.35239,564.0385)"
+       osb:paint="solid"
+       id="linearGradient19282-4">
+      <stop
+         id="stop19284-0"
+         offset="0"
+         style="stop-color:#bebebe;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       gradientTransform="translate(299.26416,297.36914)"
+       gradientUnits="userSpaceOnUse"
+       y2="305.36914"
+       x2="311.70312"
+       y1="305.36914"
+       x1="295.70312"
+       id="linearGradient7060"
+       xlink:href="#linearGradient19282-4" />
+    <linearGradient
+       gradientTransform="matrix(0.625,0,0,0.62500005,5.22565,3.0008792)"
+       gradientUnits="userSpaceOnUse"
+       y2="305.36914"
+       x2="311.70312"
+       y1="305.36914"
+       x1="295.70312"
+       id="linearGradient7060-0"
+       xlink:href="#linearGradient19282-4" />
+  </defs>
+  <g
+     id="gimp-tool-offset">
+    <rect
+       y="1.5008754"
+       x="1.5"
+       height="13"
+       width="13"
+       id="rect7909"
+       
style="fill:none;fill-rule:evenodd;stroke:#bebebe;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 />
+    <path
+       inkscape:connector-curvature="0"
+       
style="display:inline;fill:url(#linearGradient7060-0);fill-opacity:1;stroke:none;stroke-width:0.99999994"
+       d="M 8.0134312,3.000875 6.125,4.8856439 H 7.3945375 V 7.3990691 C 6.5549062,7.3927566 
5.714875,7.3858816 4.875,7.3807566 V 6.134419 L 3,7.9935504 4.875,9.8795376 V 8.6258755 c 0.83985,-5.63e-5 
1.6796812,-0.00188 2.5195375,0 V 9.8758751 11.128319 H 6.125 L 8.0134312,13.000875 9.875,11.128319 H 8.625 V 
9.8758751 8.6258755 c 0.8333375,5.625e-4 1.666675,0.0025 2.5,0 V 9.8795376 L 13,7.9935504 11.125,6.134419 v 
1.2475626 c -0.833263,0.014688 -1.6663559,0.02425 -2.5,0.021938 V 4.8856127 h 1.25 z"
+       id="path74740" />
+  </g>
+</svg>
diff --git a/icons/Symbolic/symbolic-scalable.svg b/icons/Symbolic/symbolic-scalable.svg
index a859cabf83..4e1b8d8121 100644
--- a/icons/Symbolic/symbolic-scalable.svg
+++ b/icons/Symbolic/symbolic-scalable.svg
@@ -15,7 +15,7 @@
    width="1322.0306"
    height="388.46494"
    id="svg7384"
-   inkscape:version="0.92.3 (2405546, 2018-03-11)"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
    sodipodi:docname="symbolic-scalable.svg"
    viewBox="0 0 1322.0306 388.46493">
   <metadata
@@ -26,7 +26,7 @@
         <dc:format>image/svg+xml</dc:format>
         <dc:type
            rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
-        <dc:title />
+        <dc:title></dc:title>
         <dc:contributor>
           <cc:Agent>
             <dc:title>Barbara Muraus, Jakub Steiner, Klaus Staedtler</dc:title>
@@ -50,8 +50,8 @@
      id="namedview88"
      showgrid="true"
      inkscape:zoom="1"
-     inkscape:cx="788.00815"
-     inkscape:cy="59.704507"
+     inkscape:cx="866.02514"
+     inkscape:cy="104.68616"
      inkscape:window-x="65"
      inkscape:window-y="24"
      inkscape:window-maximized="1"
@@ -18622,6 +18622,24 @@
        x2="808.99139"
        y2="211.67809"
        gradientTransform="matrix(0.99912557,0,0,1,-633.85747,-167.42187)" />
+    <linearGradient
+       gradientTransform="matrix(0.625,0,0,0.62500005,5.22565,3.0008792)"
+       gradientUnits="userSpaceOnUse"
+       y2="305.36914"
+       x2="311.70312"
+       y1="305.36914"
+       x1="295.70312"
+       id="linearGradient7060-0"
+       xlink:href="#linearGradient8670" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient19282-4"
+       id="linearGradient12792"
+       gradientUnits="userSpaceOnUse"
+       x1="295.70312"
+       y1="305.36914"
+       x2="311.70312"
+       y2="305.36914" />
   </defs>
   <g
      inkscape:groupmode="layer"
@@ -41474,6 +41492,50 @@
          id="rect22283"
          
style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 />
     </g>
+    <g
+       style="display:inline"
+       transform="matrix(0.99912557,0,0,1,-365.07765,87.29202)"
+       id="gimp-tool-offset">
+      <rect
+         y="1.5008754"
+         x="1.5"
+         height="13"
+         width="13"
+         id="rect7909"
+         
style="fill:none;fill-rule:evenodd;stroke:#bebebe;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 />
+      <path
+         inkscape:connector-curvature="0"
+         
style="display:inline;fill:url(#linearGradient7060-0);fill-opacity:1;stroke:none;stroke-width:0.99999994"
+         d="M 8.0134312,3.000875 6.125,4.8856439 H 7.3945375 V 7.3990691 C 6.5549062,7.3927566 
5.714875,7.3858816 4.875,7.3807566 V 6.134419 L 3,7.9935504 4.875,9.8795376 V 8.6258755 c 0.83985,-5.63e-5 
1.6796812,-0.00188 2.5195375,0 V 9.8758751 11.128319 H 6.125 L 8.0134312,13.000875 9.875,11.128319 H 8.625 V 
9.8758751 8.6258755 c 0.8333375,5.625e-4 1.666675,0.0025 2.5,0 V 9.8795376 L 13,7.9935504 11.125,6.134419 v 
1.2475626 c -0.833263,0.014688 -1.6663559,0.02425 -2.5,0.021938 V 4.8856127 h 1.25 z"
+         id="path74740-6" />
+    </g>
+    <g
+       style="display:inline"
+       transform="matrix(0.99912557,0,0,1,-192.22893,-948.06929)"
+       id="gimp-tool-offset-5">
+      <rect
+         y="1029.8622"
+         x="1.5"
+         height="21"
+         width="21"
+         id="rect3623"
+         
style="fill:none;fill-rule:evenodd;stroke:#bebebe;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 />
+      <g
+         inkscape:export-ydpi="123.75"
+         inkscape:export-xdpi="123.75"
+         transform="matrix(0.9999675,0,0,0.9999675,-96.996396,835.36912)"
+         inkscape:label="gimp-tool-move"
+         id="gimp-tool-move-3"
+         style="display:inline;stroke-width:1.50000012">
+        <path
+           sodipodi:nodetypes="ccccccccccccccccccccccccc"
+           inkscape:connector-curvature="0"
+           id="path74740-5"
+           transform="translate(-194.70344,-100.37001)"
+           d="m 303.70338,297.3695 -3.33336,2.66678 h 2.66667 v 4.67756 c -1.34341,-0.0101 -3.32302,-0.0211 
-4.66682,-0.0293 v -2.64822 l -2.66675,3.33344 2.66675,3.33344 v -2.66675 c 1.34376,-9e-5 3.32305,-0.003 
4.66682,0 0,1.5556 0,3.11121 0,4.66681 h -2.66683 l 3.33352,2.66676 3.33344,-2.66676 h -2.66675 c 0,-1.5556 
0,-3.11121 0,-4.66681 1.33334,9e-4 3.33349,0.004 4.66681,0 v 2.66675 l 2.66676,-3.33344 -2.66676,-3.33344 v 
2.65018 c -1.33322,0.0235 -3.33298,0.0388 -4.66681,0.0351 v -4.68537 h 2.66675 z"
+           style="fill:url(#linearGradient12792);fill-opacity:1;stroke:none;stroke-width:1.50000012" />
+      </g>
+    </g>
   </g>
   <text
      xml:space="preserve"
diff --git a/libgimpwidgets/gimpicons.h b/libgimpwidgets/gimpicons.h
index e8ebe535e1..8a3cf1ae0c 100644
--- a/libgimpwidgets/gimpicons.h
+++ b/libgimpwidgets/gimpicons.h
@@ -362,6 +362,7 @@ G_BEGIN_DECLS
 #define GIMP_ICON_TOOL_MOVE                 "gimp-tool-move"
 #define GIMP_ICON_TOOL_MYPAINT_BRUSH        "gimp-tool-mypaint-brush"
 #define GIMP_ICON_TOOL_N_POINT_DEFORMATION  "gimp-tool-n-point-deformation"
+#define GIMP_ICON_TOOL_OFFSET               "gimp-tool-offset"
 #define GIMP_ICON_TOOL_PAINTBRUSH           "gimp-tool-paintbrush"
 #define GIMP_ICON_TOOL_PATH                 "gimp-tool-path"
 #define GIMP_ICON_TOOL_PENCIL               "gimp-tool-pencil"
diff --git a/menus/image-menu.xml.in b/menus/image-menu.xml.in
index 48a4a70558..f04586f61e 100644
--- a/menus/image-menu.xml.in
+++ b/menus/image-menu.xml.in
@@ -523,7 +523,7 @@
           <menuitem action="tools-rotate-arbitrary" />
         </placeholder>
         <separator />
-        <menuitem action="drawable-offset" />
+        <menuitem action="filters-offset" />
       </menu>
 
 <!-- Layer Properties
diff --git a/po/POTFILES.in b/po/POTFILES.in
index aa10629a75..b6a897aab6 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -229,7 +229,6 @@ app/dialogs/layer-add-mask-dialog.c
 app/dialogs/layer-options-dialog.c
 app/dialogs/lebl-dialog.c
 app/dialogs/module-dialog.c
-app/dialogs/offset-dialog.c
 app/dialogs/palette-import-dialog.c
 app/dialogs/preferences-dialog.c
 app/dialogs/print-size-dialog.c
@@ -470,6 +469,7 @@ app/tools/gimpmybrushoptions-gui.c
 app/tools/gimpmybrushtool.c
 app/tools/gimpnpointdeformationoptions.c
 app/tools/gimpnpointdeformationtool.c
+app/tools/gimpoffsettool.c
 app/tools/gimpoperationtool.c
 app/tools/gimppaintbrushtool.c
 app/tools/gimppaintoptions-gui.c


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]