summaryrefslogtreecommitdiffstats
path: root/src/ui/tools/flood-tool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/tools/flood-tool.cpp')
-rw-r--r--src/ui/tools/flood-tool.cpp81
1 files changed, 47 insertions, 34 deletions
diff --git a/src/ui/tools/flood-tool.cpp b/src/ui/tools/flood-tool.cpp
index 748c82717..6e1d085aa 100644
--- a/src/ui/tools/flood-tool.cpp
+++ b/src/ui/tools/flood-tool.cpp
@@ -18,14 +18,14 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
+#include <cmath>
#include "trace/potrace/inkscape-potrace.h"
#include <2geom/pathvector.h>
#include <gdk/gdkkeysyms.h>
#include <queue>
-#include <deque>
#include <glibmm/i18n.h>
#include "color.h"
@@ -36,7 +36,6 @@
#include "display/cairo-utils.h"
#include "display/drawing-context.h"
#include "display/drawing-image.h"
-#include "display/drawing-item.h"
#include "display/drawing.h"
#include "display/sp-canvas.h"
#include "document.h"
@@ -47,23 +46,15 @@
#include "macros.h"
#include "message-context.h"
#include "message-stack.h"
-#include "preferences.h"
#include "rubberband.h"
#include "selection.h"
#include "ui/shape-editor.h"
-#include "sp-defs.h"
-#include "sp-item.h"
#include "splivarot.h"
#include "sp-namedview.h"
-#include "sp-object.h"
-#include "sp-path.h"
-#include "sp-rect.h"
#include "sp-root.h"
#include "svg/svg.h"
#include "trace/imagemap.h"
-#include "trace/trace.h"
#include "xml/node-event-vector.h"
-#include "xml/repr.h"
#include "verbs.h"
#include "pixmaps/cursor-paintbucket.xpm"
@@ -99,10 +90,10 @@ Glib::ustring ch_init[8] = {
const std::vector<Glib::ustring> FloodTool::channel_list( ch_init, ch_init+8 );
Glib::ustring gap_init[4] = {
- C_("Flood autogap", "None"),
- C_("Flood autogap", "Small"),
- C_("Flood autogap", "Medium"),
- C_("Flood autogap", "Large")
+ NC_("Flood autogap", "None"),
+ NC_("Flood autogap", "Small"),
+ NC_("Flood autogap", "Medium"),
+ NC_("Flood autogap", "Large")
};
const std::vector<Glib::ustring> FloodTool::gap_list( gap_init, gap_init+4 );
@@ -196,6 +187,21 @@ inline unsigned char * get_trace_pixel(guchar *trace_px, int x, int y, int width
}
/**
+ * \brief Check whether two unsigned integers are close to each other
+ *
+ * \param[in] a The 1st unsigned int
+ * \param[in] b The 2nd unsigned int
+ * \param[in] d The threshold for comparison
+ *
+ * \return true if |a-b| <= d; false otherwise
+ */
+static bool compare_guint32(guint32 const a, guint32 const b, guint32 const d)
+{
+ const int difference = std::abs(static_cast<int>(a) - static_cast<int>(b));
+ return difference <= d;
+}
+
+/**
* Compare a pixel in a pixel buffer with another pixel to determine if a point should be included in the fill operation.
* @param check The pixel in the pixel buffer to check.
* @param orig The original selected pixel to use as the fill target color.
@@ -206,7 +212,6 @@ inline unsigned char * get_trace_pixel(guchar *trace_px, int x, int y, int width
*/
static bool compare_pixels(guint32 check, guint32 orig, guint32 merged_orig_pixel, guint32 dtc, int threshold, PaintBucketChannels method)
{
- int diff = 0;
float hsl_check[3] = {0,0,0}, hsl_orig[3] = {0,0,0};
guint32 ac = 0, rc = 0, gc = 0, bc = 0;
@@ -232,27 +237,35 @@ static bool compare_pixels(guint32 check, guint32 orig, guint32 merged_orig_pixe
switch (method) {
case FLOOD_CHANNELS_ALPHA:
- return abs(static_cast<int>(ac) - ao) <= threshold;
+ return compare_guint32(ac, ao, threshold);
case FLOOD_CHANNELS_R:
- return abs(static_cast<int>(ac ? unpremul_alpha(rc, ac) : 0) - (ao ? unpremul_alpha(ro, ao) : 0)) <= threshold;
+ return compare_guint32(ac ? unpremul_alpha(rc, ac) : 0,
+ ao ? unpremul_alpha(ro, ao) : 0,
+ threshold);
case FLOOD_CHANNELS_G:
- return abs(static_cast<int>(ac ? unpremul_alpha(gc, ac) : 0) - (ao ? unpremul_alpha(go, ao) : 0)) <= threshold;
+ return compare_guint32(ac ? unpremul_alpha(gc, ac) : 0,
+ ao ? unpremul_alpha(go, ao) : 0,
+ threshold);
case FLOOD_CHANNELS_B:
- return abs(static_cast<int>(ac ? unpremul_alpha(bc, ac) : 0) - (ao ? unpremul_alpha(bo, ao) : 0)) <= threshold;
+ return compare_guint32(ac ? unpremul_alpha(bc, ac) : 0,
+ ao ? unpremul_alpha(bo, ao) : 0,
+ threshold);
case FLOOD_CHANNELS_RGB:
- guint32 amc, rmc, bmc, gmc;
- //amc = 255*255 - (255-ac)*(255-ad); amc = (amc + 127) / 255;
- //amc = (255-ac)*ad + 255*ac; amc = (amc + 127) / 255;
- amc = 255; // Why are we looking at desktop? Cairo version ignores destop alpha
- rmc = (255-ac)*rd + 255*rc; rmc = (rmc + 127) / 255;
- gmc = (255-ac)*gd + 255*gc; gmc = (gmc + 127) / 255;
- bmc = (255-ac)*bd + 255*bc; bmc = (bmc + 127) / 255;
-
- diff += abs(static_cast<int>(amc ? unpremul_alpha(rmc, amc) : 0) - (amop ? unpremul_alpha(rmop, amop) : 0));
- diff += abs(static_cast<int>(amc ? unpremul_alpha(gmc, amc) : 0) - (amop ? unpremul_alpha(gmop, amop) : 0));
- diff += abs(static_cast<int>(amc ? unpremul_alpha(bmc, amc) : 0) - (amop ? unpremul_alpha(bmop, amop) : 0));
- return ((diff / 3) <= ((threshold * 3) / 4));
-
+ {
+ guint32 amc, rmc, bmc, gmc;
+ //amc = 255*255 - (255-ac)*(255-ad); amc = (amc + 127) / 255;
+ //amc = (255-ac)*ad + 255*ac; amc = (amc + 127) / 255;
+ amc = 255; // Why are we looking at desktop? Cairo version ignores destop alpha
+ rmc = (255-ac)*rd + 255*rc; rmc = (rmc + 127) / 255;
+ gmc = (255-ac)*gd + 255*gc; gmc = (gmc + 127) / 255;
+ bmc = (255-ac)*bd + 255*bc; bmc = (bmc + 127) / 255;
+
+ int diff = 0; // The total difference between each of the 3 color components
+ diff += std::abs(static_cast<int>(amc ? unpremul_alpha(rmc, amc) : 0) - static_cast<int>(amop ? unpremul_alpha(rmop, amop) : 0));
+ diff += std::abs(static_cast<int>(amc ? unpremul_alpha(gmc, amc) : 0) - static_cast<int>(amop ? unpremul_alpha(gmop, amop) : 0));
+ diff += std::abs(static_cast<int>(amc ? unpremul_alpha(bmc, amc) : 0) - static_cast<int>(amop ? unpremul_alpha(bmop, amop) : 0));
+ return ((diff / 3) <= ((threshold * 3) / 4));
+ }
case FLOOD_CHANNELS_H:
return ((int)(fabs(hsl_check[0] - hsl_orig[0]) * 100.0) <= threshold);
case FLOOD_CHANNELS_S:
@@ -456,7 +469,7 @@ static void do_trace(bitmap_coords_info bci, guchar *trace_px, SPDesktop *deskto
ngettext("Area filled, path with <b>%d</b> node created and unioned with selection.","Area filled, path with <b>%d</b> nodes created and unioned with selection.",
SP_PATH(reprobj)->nodesInPath()), SP_PATH(reprobj)->nodesInPath() );
selection->add(reprobj);
- sp_selected_path_union_skip_undo(desktop->getSelection(), desktop);
+ selection->pathUnion(true);
} else {
desktop->messageStack()->flashF( Inkscape::WARNING_MESSAGE,
ngettext("Area filled, path with <b>%d</b> node created.","Area filled, path with <b>%d</b> nodes created.",