From b26ef4ad395201f6d11399298556daff04f58402 Mon Sep 17 00:00:00 2001 From: ishmal Date: Wed, 5 Jul 2006 21:37:13 +0000 Subject: [PATCH] refactoring, add background removal --- src/trace/potrace/inkscape-potrace.cpp | 154 +++++++++---------------- src/trace/potrace/inkscape-potrace.h | 26 +++-- src/trace/trace.cpp | 21 ++-- src/trace/trace.h | 51 ++++---- src/ui/dialog/tracedialog.cpp | 14 ++- 5 files changed, 125 insertions(+), 141 deletions(-) diff --git a/src/trace/potrace/inkscape-potrace.cpp b/src/trace/potrace/inkscape-potrace.cpp index e18abb338..404d25d3a 100644 --- a/src/trace/potrace/inkscape-potrace.cpp +++ b/src/trace/potrace/inkscape-potrace.cpp @@ -363,7 +363,8 @@ PotraceTracingEngine::preview(Glib::RefPtr 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 +PotraceTracingEngine::traceSingle(GdkPixbuf * thePixbuf) { + std::vector 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 +PotraceTracingEngine::traceBrightnessMulti(GdkPixbuf * thePixbuf) { + std::vector 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 +PotraceTracingEngine::traceQuant(GdkPixbuf * thePixbuf) { + std::vector 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 element. */ -TracingEngineResult * -PotraceTracingEngine::trace(Glib::RefPtr pixbuf, - int *nrPaths) +std::vector +PotraceTracingEngine::trace(Glib::RefPtr pixbuf) { GdkPixbuf *thePixbuf = pixbuf->gobj(); @@ -685,15 +645,15 @@ PotraceTracingEngine::trace(Glib::RefPtr 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); } } diff --git a/src/trace/potrace/inkscape-potrace.h b/src/trace/potrace/inkscape-potrace.h index 0f257cb95..f3459159f 100644 --- a/src/trace/potrace/inkscape-potrace.h +++ b/src/trace/potrace/inkscape-potrace.h @@ -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 element. */ - virtual TracingEngineResult *trace(Glib::RefPtr pixbuf, - int *nrPaths); + virtual std::vector trace( + Glib::RefPtr 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::vectortraceBrightnessMulti(GdkPixbuf *pixbuf); + std::vectortraceQuant(GdkPixbuf *pixbuf); + std::vectortraceSingle(GdkPixbuf *pixbuf); };//class PotraceTracingEngine diff --git a/src/trace/trace.cpp b/src/trace/trace.cpp index 13885eb5b..3173d057e 100644 --- a/src/trace/trace.cpp +++ b/src/trace/trace.cpp @@ -462,12 +462,13 @@ void Tracer::traceThread() return; } - int nrPaths; - TracingEngineResult *results = engine->trace(pixbuf, &nrPaths); - //printf("nrPaths:%d\n", nrPaths); + std::vector 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 ; igetNodeCount(); + 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) { diff --git a/src/trace/trace.h b/src/trace/trace.h index 5e2c0799d..02290436a 100644 --- a/src/trace/trace.h +++ b/src/trace/trace.h @@ -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 element. */ - virtual TracingEngineResult *trace(Glib::RefPtr pixbuf, - int *nrPaths) - { return NULL; } + virtual std::vector trace( + Glib::RefPtr pixbuf) + { std::vector dummy; return dummy; } /** diff --git a/src/ui/dialog/tracedialog.cpp b/src/ui/dialog/tracedialog.cpp index 967ed4327..6182954f6 100644 --- a/src/ui/dialog/tracedialog.cpp +++ b/src/ui/dialog/tracedialog.cpp @@ -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 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")); -- 2.30.2