Code

refactoring, add background removal
authorishmal <ishmal@users.sourceforge.net>
Wed, 5 Jul 2006 21:37:13 +0000 (21:37 +0000)
committerishmal <ishmal@users.sourceforge.net>
Wed, 5 Jul 2006 21:37:13 +0000 (21:37 +0000)
src/trace/potrace/inkscape-potrace.cpp
src/trace/potrace/inkscape-potrace.h
src/trace/trace.cpp
src/trace/trace.h
src/ui/dialog/tracedialog.cpp

index e18abb3381b3c67dad482890d827eb80a9c33172..404d25d3a18c87f16bedfc5877c84edd13b47255 100644 (file)
@@ -363,7 +363,8 @@ PotraceTracingEngine::preview(Glib::RefPtr<Gdk::Pixbuf> thePixbuf)
 
 
 //*This is the core inkscape-to-potrace binding
-char *PotraceTracingEngine::grayMapToPath(GrayMap *grayMap, long *nodeCount)
+std::string
+PotraceTracingEngine::grayMapToPath(GrayMap *grayMap, long *nodeCount)
 {
 
     /* get default parameters */
@@ -395,7 +396,7 @@ char *PotraceTracingEngine::grayMapToPath(GrayMap *grayMap, long *nodeCount)
     if (!keepGoing)
         {
         g_warning("aborted");
-        return NULL;
+        return "";
         }
 
     /* trace a bitmap*/
@@ -410,7 +411,7 @@ char *PotraceTracingEngine::grayMapToPath(GrayMap *grayMap, long *nodeCount)
         g_warning("aborted");
         potrace_state_free(potraceState);
         potrace_param_free(potraceParams);
-        return NULL;
+        return "";
         }
 
     Inkscape::SVGOStringStream data;
@@ -426,13 +427,12 @@ char *PotraceTracingEngine::grayMapToPath(GrayMap *grayMap, long *nodeCount)
     potrace_param_free(potraceParams);
 
     if (!keepGoing)
-        return NULL;
+        return "";
 
-    char *d = strdup((char *)data.str().c_str());
+    std::string d = data.str();
     if ( nodeCount)
         *nodeCount = thisNodeCount;
 
-
     return d;
 
 }
@@ -442,51 +442,47 @@ char *PotraceTracingEngine::grayMapToPath(GrayMap *grayMap, long *nodeCount)
 /**
  *  This is called for a single scan
  */
-TracingEngineResult *
-PotraceTracingEngine::traceSingle(GdkPixbuf * thePixbuf, int *nrPaths)
+std::vector<TracingEngineResult>
+PotraceTracingEngine::traceSingle(GdkPixbuf * thePixbuf)
 {
 
+    std::vector<TracingEngineResult> results;
+
     if (!thePixbuf)
-        return NULL;
+        return results;
 
     brightnessFloor = 0.0; //important to set this
 
     GrayMap *grayMap = filter(*this, thePixbuf);
     if (!grayMap)
-        return NULL;
+        return results;
 
     long nodeCount;
-    char *d = grayMapToPath(grayMap, &nodeCount);
+    std::string d = grayMapToPath(grayMap, &nodeCount);
 
     grayMap->destroy(grayMap);
 
-    if (!d)
-        {
-        *nrPaths = 0;
-        return NULL;
-        }
     char *style = "fill:#000000";
 
     //g_message("### GOT '%s' \n", d);
-    TracingEngineResult *result = new TracingEngineResult(style, d, nodeCount);
-
-    free(d);
-
-    *nrPaths = 1;
+    TracingEngineResult result(style, d, nodeCount);
+    results.push_back(result);
 
-    return result;
+    return results;
 }
 
 
 /**
  *  Called for multiple-scanning algorithms
  */
-TracingEngineResult *
-PotraceTracingEngine::traceBrightnessMulti(GdkPixbuf * thePixbuf, int *nrPaths)
+std::vector<TracingEngineResult>
+PotraceTracingEngine::traceBrightnessMulti(GdkPixbuf * thePixbuf)
 {
 
+    std::vector<TracingEngineResult> results;
+
     if (!thePixbuf)
-        return NULL;
+        return results;
 
     double low     = 0.2; //bottom of range
     double high    = 0.9; //top of range
@@ -496,7 +492,6 @@ PotraceTracingEngine::traceBrightnessMulti(GdkPixbuf * thePixbuf, int *nrPaths)
 
     int traceCount = 0;
 
-    TracingEngineResult *results = NULL;
     for ( brightnessThreshold = low ;
           brightnessThreshold <= high ;
           brightnessThreshold += delta)
@@ -505,18 +500,15 @@ PotraceTracingEngine::traceBrightnessMulti(GdkPixbuf * thePixbuf, int *nrPaths)
 
         GrayMap *grayMap = filter(*this, thePixbuf);
         if (!grayMap)
-            return NULL;
+            return results;
 
         long nodeCount;
-        char *d = grayMapToPath(grayMap, &nodeCount);
+        std::string d = grayMapToPath(grayMap, &nodeCount);
 
         grayMap->destroy(grayMap);
 
-        if (!d)
-            {
-            *nrPaths = 0;
-            return NULL;
-            }
+        if (d.size() == 0)
+            return results;
 
         int grayVal = (int)(256.0 * brightnessThreshold);
         char style[31];
@@ -524,22 +516,8 @@ PotraceTracingEngine::traceBrightnessMulti(GdkPixbuf * thePixbuf, int *nrPaths)
                     grayVal, grayVal, grayVal);
 
         //g_message("### GOT '%s' \n", d);
-        TracingEngineResult *result = new TracingEngineResult(style, d, nodeCount);
-
-        free(d);
-
-        if (!results)
-            {
-            results = result; //first one
-            }
-        else
-            {
-            //walk to end of list
-            TracingEngineResult *r;
-            for (r=results ; r->next ; r=r->next)
-                {}
-            r->next = result;
-            }
+        TracingEngineResult result(style, d, nodeCount);
+        results.push_back(result);
 
         if (!multiScanStack)
             brightnessFloor = brightnessThreshold;
@@ -553,9 +531,12 @@ PotraceTracingEngine::traceBrightnessMulti(GdkPixbuf * thePixbuf, int *nrPaths)
             }
         }
 
-    //report the count of paths processed
-    *nrPaths = multiScanNrColors;
-
+    //# Remove the bottom-most scan, if requested
+    if (results.size() > 1 && multiScanRemoveBackground)
+        {
+        g_message("remove background");
+        results.erase(results.end() - 1);
+        }
 
     return results;
 }
@@ -564,18 +545,18 @@ PotraceTracingEngine::traceBrightnessMulti(GdkPixbuf * thePixbuf, int *nrPaths)
 /**
  *  Quantization
  */
-TracingEngineResult *
-PotraceTracingEngine::traceQuant(GdkPixbuf * thePixbuf, int *nrPaths)
+std::vector<TracingEngineResult>
+PotraceTracingEngine::traceQuant(GdkPixbuf * thePixbuf)
 {
 
+    std::vector<TracingEngineResult> results;
+
     if (!thePixbuf)
-        return NULL;
+        return results;
 
     IndexedMap *iMap = filterIndexed(*this, thePixbuf);
     if (!iMap)
-        return NULL;
-
-    TracingEngineResult *results = NULL;
+        return results;
 
     //Create and clear a gray map
     GrayMap *gm = GrayMapCreate(iMap->width, iMap->height);
@@ -607,13 +588,10 @@ PotraceTracingEngine::traceQuant(GdkPixbuf * thePixbuf, int *nrPaths)
 
         //## Now we have a traceable graymap
         long nodeCount;
-        char *d = grayMapToPath(gm, &nodeCount);
+        std::string d = grayMapToPath(gm, &nodeCount);
 
-        if (!d)
-            {
-            *nrPaths = 0;
-            return NULL;
-            }
+        if (d.size() == 0)
+            return results;
 
         //### get style info
         char style[13];
@@ -621,29 +599,8 @@ PotraceTracingEngine::traceQuant(GdkPixbuf * thePixbuf, int *nrPaths)
         sprintf(style, "fill:#%02x%02x%02x", rgb.r, rgb.g, rgb.b);
 
         //g_message("### GOT '%s' \n", d);
-        TracingEngineResult *result = new TracingEngineResult(style, d, nodeCount);
-
-        free(d);
-
-        if (!results)
-            {
-            results = result; //first one
-            }
-        else
-            {
-            //prepend
-            /*
-            result->next = results;
-            results = result;
-            */
-
-            //append
-            TracingEngineResult *r;
-            for (r=results ; r->next ; r=r->next)
-                {}
-            r->next = result;
-            }
-
+        TracingEngineResult result(style, d, nodeCount);
+        results.push_back(result);
 
         SPDesktop *desktop = SP_ACTIVE_DESKTOP;
         if (desktop)
@@ -654,14 +611,18 @@ PotraceTracingEngine::traceQuant(GdkPixbuf * thePixbuf, int *nrPaths)
             }
 
 
-        }
-
-    //report the count of paths processed
-    *nrPaths = iMap->nrColors;
+        }// for colorIndex
 
     gm->destroy(gm);
     iMap->destroy(iMap);
 
+    //# Remove the bottom-most scan, if requested
+    if (results.size() > 1 && multiScanRemoveBackground)
+        {
+        g_message("remove background");
+        results.erase(results.end() - 1);
+        }
+
     return results;
 }
 
@@ -672,9 +633,8 @@ PotraceTracingEngine::traceQuant(GdkPixbuf * thePixbuf, int *nrPaths)
  *  return the path data that is compatible with the d="" attribute
  *  of an SVG <path> element.
  */
-TracingEngineResult *
-PotraceTracingEngine::trace(Glib::RefPtr<Gdk::Pixbuf> pixbuf,
-                            int *nrPaths)
+std::vector<TracingEngineResult>
+PotraceTracingEngine::trace(Glib::RefPtr<Gdk::Pixbuf> pixbuf)
 {
 
     GdkPixbuf *thePixbuf = pixbuf->gobj();
@@ -685,15 +645,15 @@ PotraceTracingEngine::trace(Glib::RefPtr<Gdk::Pixbuf> pixbuf,
     if ( traceType == TRACE_QUANT_COLOR ||
          traceType == TRACE_QUANT_MONO   )
         {
-        return traceQuant(thePixbuf, nrPaths);
+        return traceQuant(thePixbuf);
         }
     else if ( traceType == TRACE_BRIGHTNESS_MULTI )
         {
-        return traceBrightnessMulti(thePixbuf, nrPaths);
+        return traceBrightnessMulti(thePixbuf);
         }
     else
         {
-        return traceSingle(thePixbuf, nrPaths);
+        return traceSingle(thePixbuf);
         }
 }
 
index 0f257cb95833903b2b50d6ee000658ce5f4a1715..f3459159f3b79c358448bce1064b6813f7de6132 100644 (file)
@@ -158,6 +158,18 @@ class PotraceTracingEngine : public TracingEngine
         return multiScanSmooth;
         }
 
+    /**
+     * Sets whether we want to remove the background (bottom) trace
+     */
+    void setMultiScanRemoveBackground(bool val)
+        {
+        multiScanRemoveBackground= val;
+        }
+    bool getMultiScanRemoveBackground()
+        {
+        return multiScanRemoveBackground;
+        }
+
 
     /**
      *  This is the working method of this implementing class, and all
@@ -165,8 +177,8 @@ class PotraceTracingEngine : public TracingEngine
      *  return the path data that is compatible with the d="" attribute
      *  of an SVG <path> element.
      */
-    virtual TracingEngineResult *trace(Glib::RefPtr<Gdk::Pixbuf> pixbuf,
-                                       int *nrPaths);
+    virtual std::vector<TracingEngineResult> trace(
+                        Glib::RefPtr<Gdk::Pixbuf> pixbuf);
 
     /**
      *  Abort the thread that is executing getPathDataFromPixbuf()
@@ -206,16 +218,16 @@ class PotraceTracingEngine : public TracingEngine
     int multiScanNrColors;
     bool multiScanStack; //do we tile or stack?
     bool multiScanSmooth;//do we use gaussian filter?
-
+    bool multiScanRemoveBackground; //do we remove the bottom trace?
     /**
      * This is the actual wrapper of the call to Potrace.  nodeCount
      * returns the count of nodes created.  May be NULL if ignored.
      */
-    char *grayMapToPath(GrayMap *gm, long *nodeCount);
+    std::string grayMapToPath(GrayMap *gm, long *nodeCount);
 
-    TracingEngineResult *traceBrightnessMulti(GdkPixbuf *pixbuf, int *nrPaths);
-    TracingEngineResult *traceQuant(GdkPixbuf *pixbuf, int *nrPaths);
-    TracingEngineResult *traceSingle(GdkPixbuf *pixbuf, int *nrPaths);
+    std::vector<TracingEngineResult>traceBrightnessMulti(GdkPixbuf *pixbuf);
+    std::vector<TracingEngineResult>traceQuant(GdkPixbuf *pixbuf);
+    std::vector<TracingEngineResult>traceSingle(GdkPixbuf *pixbuf);
 
 
 };//class PotraceTracingEngine
index 13885eb5bf2082a2c133a7faa897fc8d1941a5fe..3173d057eb60ace164a9553f2d74ab9f48d2ab7e 100644 (file)
@@ -462,12 +462,13 @@ void Tracer::traceThread()
         return;
         }
 
-    int nrPaths;
-    TracingEngineResult *results = engine->trace(pixbuf, &nrPaths);
-    //printf("nrPaths:%d\n", nrPaths);
+    std::vector<TracingEngineResult> results =
+                engine->trace(pixbuf);
+    //printf("nrPaths:%d\n", results.size());
+    int nrPaths = results.size();
 
     //### Check if we should stop
-    if (!keepGoing || !results || nrPaths<1)
+    if (!keepGoing || nrPaths<1)
         {
         engine = NULL;
         return;
@@ -523,14 +524,14 @@ void Tracer::traceThread()
 
     long totalNodeCount = 0L;
 
-    for (TracingEngineResult *result=results ;
-                  result ; result=result->next)
+    for (unsigned int i=0 ; i<results.size() ; i++)
         {
-        totalNodeCount += result->getNodeCount();
+        TracingEngineResult result = results[i];
+        totalNodeCount += result.getNodeCount();
 
         Inkscape::XML::Node *pathRepr = sp_repr_new("svg:path");
-        pathRepr->setAttribute("style", result->getStyle());
-        pathRepr->setAttribute("d",     result->getPathData());
+        pathRepr->setAttribute("style", result.getStyle().c_str());
+        pathRepr->setAttribute("d",     result.getPathData().c_str());
 
         if (nrPaths > 1)
             groupRepr->addChild(pathRepr, NULL);
@@ -552,8 +553,6 @@ void Tracer::traceThread()
         Inkscape::GC::release(pathRepr);
         }
 
-    delete results;
-
     // If we have a group, then focus on, then forget it
     if (nrPaths > 1)
         {
index 5e2c0799d7197cd7a9d1ff352b9340d13125a3a4..02290436ad7a96e49da27a36880394ce6fdb2c2d 100644 (file)
@@ -49,38 +49,39 @@ public:
     /**
      *
      */
-    TracingEngineResult(char *theStyle, char *thePathData, long theNodeCount)
+    TracingEngineResult(const std::string &theStyle,
+                        const std::string &thePathData,
+                        long theNodeCount)
         {
-        next      = NULL;
-        style     = strdup(theStyle);
-        pathData  = strdup(thePathData);
+        style     = theStyle;
+        pathData  = thePathData;
         nodeCount = theNodeCount;
         }
 
+    TracingEngineResult(const TracingEngineResult &other)
+        { assign(other); }
+
+    virtual TracingEngineResult &operator=(const TracingEngineResult &other)
+        { assign(other); return *this; }
+
+
     /**
      *
      */
     virtual ~TracingEngineResult()
-        {
-        if (next)
-            delete next;
-        if (style)
-            free(style);
-        if (pathData)
-            free(pathData);
-        }
+        { }
 
 
     /**
      *
      */
-    char *getStyle()
+    std::string getStyle()
         { return style; }
 
     /**
      *
      */
-    char *getPathData()
+    std::string getPathData()
         { return pathData; }
 
     /**
@@ -89,16 +90,18 @@ public:
     long getNodeCount()
         { return nodeCount; }
 
-    /**
-     *
-     */
-    TracingEngineResult *next;
-
 private:
 
-    char *style;
+    void assign(const TracingEngineResult &other)
+        {
+        style = other.style;
+        pathData = other.pathData;
+        nodeCount = other.nodeCount;
+        }
+
+    std::string style;
 
-    char *pathData;
+    std::string pathData;
 
     long nodeCount;
 
@@ -133,9 +136,9 @@ class TracingEngine
      *  compatible with the d="" attribute
      *  of an SVG <path> element.
      */
-    virtual  TracingEngineResult *trace(Glib::RefPtr<Gdk::Pixbuf> pixbuf,
-                                        int *nrPaths)
-        { return NULL; }
+    virtual  std::vector<TracingEngineResult> trace(
+                           Glib::RefPtr<Gdk::Pixbuf> pixbuf)
+        { std::vector<TracingEngineResult> dummy;  return dummy; }
 
 
     /**
index 967ed43275e4e05526131b2afea1e27f42b36e6e..6182954f6e090c783b05e171dc8728b5e6a62580 100644 (file)
@@ -136,13 +136,14 @@ class TraceDialogImpl : public TraceDialog
 
     Gtk::HBox             potraceMultiScanHBox2;
     Gtk::RadioButton      potraceMultiScanColorRadioButton;
-    Gtk::CheckButton      potraceMultiScanStackButton;
 
     Gtk::HBox             potraceMultiScanHBox3;
     Gtk::RadioButton      potraceMultiScanMonoRadioButton;
     Gtk::Label            potraceMultiScanNrColorLabel;
 
+    Gtk::CheckButton      potraceMultiScanStackButton;
     Gtk::CheckButton      potraceMultiScanSmoothButton;
+    Gtk::CheckButton      potraceMultiScanBackgroundButton;
 
 
     //preview
@@ -230,6 +231,8 @@ void TraceDialogImpl::potraceProcess(bool do_i_trace)
     pte.setMultiScanStack(do_i_stack);
     bool do_i_smooth = potraceMultiScanSmoothButton.get_active();
     pte.setMultiScanSmooth(do_i_smooth);
+    bool do_i_remove_background = potraceMultiScanBackgroundButton.get_active();
+    pte.setMultiScanRemoveBackground(do_i_remove_background);
 
     //##### Get intermediate bitmap image
     Glib::RefPtr<Gdk::Pixbuf> pixbuf = tracer.getSelectedImage();
@@ -342,7 +345,7 @@ TraceDialogImpl::TraceDialogImpl()
 
     /*#### SIOX ####*/
     //# for now, put at the top of the potrace box.  something better later
-    sioxButton.set_label(_("SIOX foreground selection (experimental)"));
+    sioxButton.set_label(_("SIOX foreground selection"));
     sioxBox.pack_start(sioxButton, false, false, MARGIN);
     tips.set_tip(sioxButton, 
         _("Cover the area you want to select as the foreground"));
@@ -461,6 +464,12 @@ TraceDialogImpl::TraceDialogImpl()
     tips.set_tip(potraceMultiScanColorRadioButton, _("Trace the given number of reduced colors"));
 
 
+    // TRANSLATORS: "Layer" refers to one of the stacked paths in the multiscan
+    potraceMultiScanBackgroundButton.set_label(_("Remove background"));
+    potraceMultiScanBackgroundButton.set_active(false);
+    potraceMultiScanHBox2.pack_end(potraceMultiScanBackgroundButton, false, false, MARGIN);
+    tips.set_tip(potraceMultiScanBackgroundButton, _("Remove bottom (background) layer when done"));
+
     potraceMultiScanVBox.pack_start(potraceMultiScanHBox2, false, false, MARGIN);
 
     //---Hbox3
@@ -481,6 +490,7 @@ TraceDialogImpl::TraceDialogImpl()
     potraceMultiScanHBox3.pack_end(potraceMultiScanSmoothButton, false, false, MARGIN);
     tips.set_tip(potraceMultiScanSmoothButton, _("Apply Gaussian blur to the bitmap before tracing"));
 
+
     potraceMultiScanVBox.pack_start(potraceMultiScanHBox3, false, false, MARGIN);
 
     potraceMultiScanFrame.set_label(_("Multiple Scanning"));