From ba838aef213e2b99bdedc687429c12657c669df5 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Mon, 27 May 2019 19:32:53 +0200 Subject: new trace Dialog - initial implementation --- share/ui/dialog-trace.glade | 966 +++++++++++++++++++++++++++ src/trace/CMakeLists.txt | 2 + src/trace/depixelize/inkscape-depixelize.cpp | 152 +++++ src/trace/depixelize/inkscape-depixelize.h | 100 +++ src/trace/potrace/inkscape-potrace.cpp | 35 +- src/trace/potrace/inkscape-potrace.h | 164 +---- src/ui/CMakeLists.txt | 1 + src/ui/dialog/tracedialog.cpp | 4 +- src/ui/dialog/tracedialog2.cpp | 351 ++++++++++ 9 files changed, 1599 insertions(+), 176 deletions(-) create mode 100644 share/ui/dialog-trace.glade create mode 100644 src/trace/depixelize/inkscape-depixelize.cpp create mode 100644 src/trace/depixelize/inkscape-depixelize.h create mode 100644 src/ui/dialog/tracedialog2.cpp diff --git a/share/ui/dialog-trace.glade b/share/ui/dialog-trace.glade new file mode 100644 index 000000000..ea993699a --- /dev/null +++ b/share/ui/dialog-trace.glade @@ -0,0 +1,966 @@ + + + + + + 2 + 256 + 8 + 1 + 10 + + + -10 + 10 + 1 + 0.20000000000000001 + 10 + + + -20 + 20 + 5 + 1 + 10 + + + 2 + 8 + 4 + 1 + 10 + + + -10 + 10 + 1 + 0.20000000000000001 + 10 + + + 100 + 1 + 10 + + + 1 + 0.45000000000000001 + 0.01 + 10 + + + 2 + 64 + 8 + 1 + 10 + + + 100 + 1 + 10 + + + 1 + 0.65000000000000002 + 0.01 + 10 + + + 5 + 0.20000000000000001 + 0.050000000000000003 + 10 + + + 1.3400000000000001 + 1 + 0.01 + 10 + + + 1000 + 2 + 1 + 10 + + + True + False + vertical + + + True + True + 200 + + + True + True + + + True + False + vertical + + + True + False + center + choice_scan + + + False + True + 0 + + + + + True + False + + + True + False + vertical + + + True + False + 0 + + Brightness cutoff + Edge detection + Color quantization + Autotrace + Centerline tracing (autotrace) + + + + False + True + 0 + + + + + True + False + True + + + SS_BC + True + False + + + True + False + vertical + + + True + False + Threshold (1) + + + False + True + 0 + + + + + True + True + SS_BC_T + 3 + + + False + True + 1 + + + + + SS_BC + + + + + True + False + vertical + + + True + False + Threshold (2) + + + False + True + 0 + + + + + True + True + SS_ED_T + 3 + + + False + True + 1 + + + + + SS_ED + 1 + + + + + True + False + vertical + + + True + False + Colors + + + False + True + 0 + + + + + True + True + SS_CQ_T + + + False + True + 1 + + + + + SS_CQ + 2 + + + + + True + False + vertical + + + True + False + Autotrace ? + + + False + True + 0 + + + + + True + True + SS_AT_T + 3 + + + False + True + 1 + + + + + SS_AT + 3 + + + + + True + False + vertical + + + True + False + Centerline tries + + + False + True + 0 + + + + + True + True + SS_CT_T + 3 + + + False + True + 1 + + + + + SS_CT + 4 + + + + + False + True + 0 + + + + + Invert image + True + True + False + True + + + False + True + 1 + + + + + False + True + 1 + + + + + page0 + Single scan + + + + + True + False + True + + + True + False + 0 + + Brightness steps + Colors + Grays + Autotrace (slower) + + + + 0 + 0 + 2 + + + + + Smooth + True + True + False + True + + + 1 + 1 + + + + + Stack + True + True + False + True + + + 1 + 2 + + + + + Remove background + True + True + False + True + + + 1 + 3 + + + + + True + False + Scans + + + 0 + 1 + + + + + True + True + MS_scans + + + 0 + 2 + + + + + True + False + + + 0 + 3 + + + + + page1 + Multiple scans + 1 + + + + + True + True + 1 + + + + + True + False + Options + + + + + + False + True + 2 + + + + + True + False + True + + + Speckles + True + True + False + True + True + + + 0 + 0 + + + + + Smooth corners + True + True + False + True + True + + + 0 + 1 + + + + + Optimize + True + True + False + True + True + + + 0 + 2 + + + + + True + True + speckles + + + 1 + 0 + + + + + True + True + smooth + 2 + + + 1 + 1 + + + + + True + True + optimize + 2 + 0.20000000000000001 + + + 1 + 2 + + + + + False + True + 3 + + + + + + + True + False + Trace bitmap + + + False + + + + + True + False + vertical + + + True + False + +Heuristics + + + + + + + False + True + 0 + + + + + True + False + 4 + True + + + True + False + Curves (multiplier) + + + 0 + 0 + + + + + True + False + Islands (weight) + + + 0 + 1 + + + + + True + False + Sparse pixels +(window radius) + + + 0 + 2 + + + + + True + False + Sparse pixels +(multiplier) + + + 0 + 3 + + + + + True + True + PA_curves + 3 + True + 1 + + + 1 + 0 + + + + + True + True + PA_islands + True + 5 + + + 1 + 1 + + + + + True + True + PA_sparse1 + True + 2 + + + 1 + 2 + + + + + True + True + PA_sparse2 + 3 + True + 1 + + + 1 + 3 + + + + + False + True + 1 + + + + + True + False + +Output + + + + + + + False + True + 2 + + + + + Voronoi + True + True + False + True + True + + + False + True + 3 + + + + + B-splines + True + True + False + True + True + RB_PA_voronoi + + + False + True + 4 + + + + + 1 + + + + + True + False + Pixel art + + + 1 + False + + + + + True + False + Inkscape bitmap tracing +is based on Potrace by Peter Selinger +and on autotrace + center + + + 2 + + + + + True + False + Credits + + + 2 + False + + + + + False + False + + + + + True + False + vertical + + + 200 + 200 + True + False + gtk-missing-image + 2 + + + True + True + 0 + + + + + True + False + + + + Update + True + True + True + + + False + True + 0 + + + + + SIOX + True + True + False + True + + + False + True + 1 + + + + + False + True + 1 + + + + + True + False + + + + + True + True + 0 + + + + + True + False + baseline + 3 + end + + + gtk-revert-to-saved + True + True + True + True + + + True + True + 0 + + + + + gtk-stop + True + True + True + True + + + True + True + 1 + + + + + gtk-ok + True + True + True + True + + + True + True + 2 + + + + + True + True + 1 + + + + diff --git a/src/trace/CMakeLists.txt b/src/trace/CMakeLists.txt index 02bb6a05d..a680166bf 100644 --- a/src/trace/CMakeLists.txt +++ b/src/trace/CMakeLists.txt @@ -11,6 +11,7 @@ set(trace_SRC potrace/inkscape-potrace.cpp autotrace/inkscape-autotrace.cpp + depixelize/inkscape-depixelize.cpp # ------- # Headers @@ -25,6 +26,7 @@ set(trace_SRC potrace/bitmap.h potrace/inkscape-potrace.h autotrace/inkscape-autotrace.h + depixelize/inkscape-depixelize.h ) # add_inkscape_lib(trace_LIB "${trace_SRC}") diff --git a/src/trace/depixelize/inkscape-depixelize.cpp b/src/trace/depixelize/inkscape-depixelize.cpp new file mode 100644 index 000000000..4b8bde1d8 --- /dev/null +++ b/src/trace/depixelize/inkscape-depixelize.cpp @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * This is the C++ glue between Inkscape and Potrace + * + * Authors: + * Bob Jamison + * Stéphane Gimenez + * + * Copyright (C) 2004-2006 Authors + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + * + * Potrace, the wonderful tracer located at http://potrace.sourceforge.net, + * is provided by the generosity of Peter Selinger, to whom we are grateful. + * + */ + +#include "inkscape-depixelize.h" + +#include +#include +#include +#include + +#include "desktop.h" +#include "message-stack.h" + +#include "object/sp-path.h" + +#include +#include + +using Glib::ustring; + + + +namespace Inkscape { + +namespace Trace { + +namespace Depixelize { + + +/** + * + */ +DepixelizeTracingEngine::DepixelizeTracingEngine() + : keepGoing(1) + , traceType(TRACE_VORONOI) +{ + params = new ::Tracer::Kopf2011::Options(); +} + + + +DepixelizeTracingEngine::DepixelizeTracingEngine(TraceType traceType, double curves, int islands, int sparsePixels, + double sparseMultiplier) + : keepGoing(1) + , traceType(traceType) +{ + params = new ::Tracer::Kopf2011::Options(); + params->curvesMultiplier = curves; + params->islandsWeight = islands; + params->sparsePixelsRadius = sparsePixels; + params->sparsePixelsMultiplier = sparseMultiplier; + params->nthreads = Inkscape::Preferences::get()->getIntLimited("/options/threading/numthreads", +#ifdef HAVE_OPENMP + omp_get_num_procs(), +#else + 1, +#endif // HAVE_OPENMP + 1, 256); +} + +DepixelizeTracingEngine::~DepixelizeTracingEngine() { delete params; } + +std::vector DepixelizeTracingEngine::trace(Glib::RefPtr pixbuf) +{ + if (pixbuf->get_width() > 256 || pixbuf->get_height() > 256) { + char *msg = _("Image looks too big. Process may take a while and it is" + " wise to save your document before continuing." + "\n\nContinue the procedure (without saving)?"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK_CANCEL, true); + +// if (dialog.run() != Gtk::RESPONSE_OK) +// return; +// TODO + } + + ::Tracer::Splines splines; + + if (traceType == TRACE_VORONOI) + splines = ::Tracer::Kopf2011::to_voronoi(pixbuf, *params); + else + splines = ::Tracer::Kopf2011::to_splines(pixbuf, *params); + + std::vector res; + + for (::Tracer::Splines::const_iterator it = splines.begin(), end = splines.end(); it != end; ++it) { + /*{ + SPCSSAttr *css = sp_repr_css_attr_new(); + + { + gchar b[64]; + sp_svg_write_color(b, sizeof(b), + SP_RGBA32_U_COMPOSE(unsigned(it->rgba[0]), + unsigned(it->rgba[1]), + unsigned(it->rgba[2]), + unsigned(it->rgba[3]))); + + sp_repr_css_set_property(css, "fill", b); + } + + { + Inkscape::CSSOStringStream osalpha; + osalpha << float(it->rgba[3]) / 255.; + sp_repr_css_set_property(css, "fill-opacity", + osalpha.str().c_str()); + } + + sp_repr_css_set(repr, css, "style"); + sp_repr_css_attr_unref(css); + } + + gchar *str = sp_svg_write_path(it->pathVector); + */ + + TracingEngineResult r("fill:black;", sp_svg_write_path(it->pathVector), it->pathVector.nodes().size()); //TODO + res.push_back(r); + } + return res; +} + +void DepixelizeTracingEngine::abort() { keepGoing = 0; } + +Glib::RefPtr DepixelizeTracingEngine::preview(Glib::RefPtr pixbuf) { return pixbuf; } + + +} // namespace Depixelize +} // namespace Trace +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/trace/depixelize/inkscape-depixelize.h b/src/trace/depixelize/inkscape-depixelize.h new file mode 100644 index 000000000..228e72448 --- /dev/null +++ b/src/trace/depixelize/inkscape-depixelize.h @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * This is the C++ glue between Inkscape and Potrace + * + * Copyright (C) 2019 Authors + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + * + * Potrace, the wonderful tracer located at http://potrace.sourceforge.net, + * is provided by the generosity of Peter Selinger, to whom we are grateful. + * + */ + +#ifndef __INKSCAPE_DEPIXTRACE_H__ +#define __INKSCAPE_DEPIXTRACE_H__ + +#include +#include "3rdparty/libdepixelize/kopftracer2011.h" + +struct GrayMap_def; +typedef GrayMap_def GrayMap; + +namespace Inkscape { + +namespace Trace { + +namespace Depixelize { + +enum TraceType + { + TRACE_VORONOI, + TRACE_BSPLINES + }; + + +class DepixelizeTracingEngine : public TracingEngine +{ + + public: + + /** + * + */ + DepixelizeTracingEngine(); + DepixelizeTracingEngine(TraceType traceType, double curves, int islands, int sparsePixels, double sparseMultiplier); + + /** + * + */ + ~DepixelizeTracingEngine() override; + + /** + * This is the working method of this implementing class, and all + * implementing classes. Take a GdkPixbuf, trace it, and + * return the path data that is compatible with the d="" attribute + * of an SVG element. + */ + std::vector trace( + Glib::RefPtr pixbuf) override; + + /** + * Abort the thread that is executing getPathDataFromPixbuf() + */ + void abort() override; + + /** + * + */ + Glib::RefPtr preview(Glib::RefPtr pixbuf); + + /** + * + */ + int keepGoing; + + ::Tracer::Kopf2011::Options *params; + TraceType traceType; + +};//class PotraceTracingEngine + + + +} // namespace Depixelize +} // namespace Trace +} // namespace Inkscape + + +#endif //__INKSCAPE_TRACE_H__ + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/trace/potrace/inkscape-potrace.cpp b/src/trace/potrace/inkscape-potrace.cpp index 092fba634..710e5cfa7 100644 --- a/src/trace/potrace/inkscape-potrace.cpp +++ b/src/trace/potrace/inkscape-potrace.cpp @@ -98,6 +98,15 @@ PotraceTracingEngine::PotraceTracingEngine() : potraceParams->progress.data = (void *)this; } +PotraceTracingEngine::PotraceTracingEngine(TraceType traceType, bool invert, int quantizationNrColors, double brightnessThreshold, double brightnessFloor, double cannyHighThreshold, int multiScanNrColors, bool multiScanStack, bool multiScanSmooth, bool multiScanRemoveBackground) : + keepGoing(1), traceType(traceType), invert(invert), quantizationNrColors(quantizationNrColors), brightnessThreshold(brightnessThreshold), brightnessFloor(brightnessFloor), cannyHighThreshold(cannyHighThreshold), multiScanNrColors(multiScanNrColors) , multiScanStack(multiScanStack), multiScanSmooth(multiScanSmooth), multiScanRemoveBackground(multiScanRemoveBackground) +{ + potraceParams = potrace_param_default(); + potraceParams->progress.callback = potraceStatusCallback; + potraceParams->progress.data = (void *)this; +} + + PotraceTracingEngine::~PotraceTracingEngine() { potrace_param_free(potraceParams); @@ -212,27 +221,27 @@ static GrayMap *filter(PotraceTracingEngine &engine, GdkPixbuf * pixbuf) GrayMap *newGm = nullptr; /*### Color quantization -- banding ###*/ - if (engine.getTraceType() == TRACE_QUANT) + if (engine.traceType == TRACE_QUANT) { RgbMap *rgbmap = gdkPixbufToRgbMap(pixbuf); //rgbMap->writePPM(rgbMap, "rgb.ppm"); newGm = quantizeBand(rgbmap, - engine.getQuantizationNrColors()); + engine.quantizationNrColors); rgbmap->destroy(rgbmap); //return newGm; } /*### Brightness threshold ###*/ - else if ( engine.getTraceType() == TRACE_BRIGHTNESS || - engine.getTraceType() == TRACE_BRIGHTNESS_MULTI ) + else if ( engine.traceType == TRACE_BRIGHTNESS || + engine.traceType == TRACE_BRIGHTNESS_MULTI ) { GrayMap *gm = gdkPixbufToGrayMap(pixbuf); newGm = GrayMapCreate(gm->width, gm->height); double floor = 3.0 * - ( engine.getBrightnessFloor() * 256.0 ); + ( engine.brightnessFloor * 256.0 ); double cutoff = 3.0 * - ( engine.getBrightnessThreshold() * 256.0 ); + ( engine.brightnessThreshold * 256.0 ); for (int y=0 ; yheight ; y++) { for (int x=0 ; xwidth ; x++) @@ -251,17 +260,17 @@ static GrayMap *filter(PotraceTracingEngine &engine, GdkPixbuf * pixbuf) } /*### Canny edge detection ###*/ - else if (engine.getTraceType() == TRACE_CANNY) + else if (engine.traceType == TRACE_CANNY) { GrayMap *gm = gdkPixbufToGrayMap(pixbuf); - newGm = grayMapCanny(gm, 0.1, engine.getCannyHighThreshold()); + newGm = grayMapCanny(gm, 0.1, engine.cannyHighThreshold); gm->destroy(gm); //newGm->writePPM(newGm, "canny.ppm"); //return newGm; } /*### Do I invert the image? ###*/ - if (newGm && engine.getInvert()) + if (newGm && engine.invert) { for (int y=0 ; yheight ; y++) { @@ -286,19 +295,19 @@ static IndexedMap *filterIndexed(PotraceTracingEngine &engine, GdkPixbuf * pixbu IndexedMap *newGm = nullptr; RgbMap *gm = gdkPixbufToRgbMap(pixbuf); - if (engine.getMultiScanSmooth()) + if (engine.multiScanSmooth) { RgbMap *gaussMap = rgbMapGaussian(gm); - newGm = rgbMapQuantize(gaussMap, engine.getMultiScanNrColors()); + newGm = rgbMapQuantize(gaussMap, engine.multiScanNrColors); gaussMap->destroy(gaussMap); } else { - newGm = rgbMapQuantize(gm, engine.getMultiScanNrColors()); + newGm = rgbMapQuantize(gm, engine.multiScanNrColors); } gm->destroy(gm); - if (engine.getTraceType() == TRACE_QUANT_MONO) + if (engine.traceType == TRACE_QUANT_MONO) { //Turn to grays for (int i=0 ; inrColors ; i++) diff --git a/src/trace/potrace/inkscape-potrace.h b/src/trace/potrace/inkscape-potrace.h index bed5bf457..1385521f1 100644 --- a/src/trace/potrace/inkscape-potrace.h +++ b/src/trace/potrace/inkscape-potrace.h @@ -50,170 +50,13 @@ class PotraceTracingEngine : public TracingEngine * */ PotraceTracingEngine(); + PotraceTracingEngine(TraceType traceType, bool invert, int quantizationNrColors, double brightnessThreshold, double brightnessFloor, double cannyHighThreshold, int multiScanNrColors, bool multiScanStack, bool multiScanSmooth, bool multiScanRemoveBackground); /** * */ ~PotraceTracingEngine() override; - - /** - * Sets/gets potrace parameters - */ - void setParamsTurdSize(int val) - { - potraceParams->turdsize = val; - } - int getParamsTurdSize() - { - return potraceParams->turdsize; - } - - void setParamsAlphaMax(double val) - { - potraceParams->alphamax = val; - } - double getParamsAlphaMax() - { - return potraceParams->alphamax; - } - - void setParamsOptiCurve(bool val) - { - potraceParams->opticurve = val; - } - bool getParamsOptiCurve() - { - return potraceParams->opticurve; - } - - void setParamsOptTolerance(double val) - { - potraceParams->opttolerance = val; - } - double getParamsOptTolerance() - { - return potraceParams->opttolerance; - } - - void setTraceType(TraceType val) - { - traceType = val; - } - TraceType getTraceType() - { - return traceType; - } - - /** - * Sets/gets whether I invert the product of the other filter(s) - */ - void setInvert(bool val) - { - invert = val; - } - bool getInvert() - { - return invert; - } - - /** - * Sets the halfway point for black/white - */ - void setQuantizationNrColors(int val) - { - quantizationNrColors = val; - } - int getQuantizationNrColors() - { - return quantizationNrColors; - } - - /** - * Sets the halfway point for black/white - */ - void setBrightnessThreshold(double val) - { - brightnessThreshold = val; - } - double getBrightnessThreshold() - { - return brightnessThreshold; - } - - /** - * Sets the lower consideration point for black/white - */ - void setBrightnessFloor(double val) - { - brightnessFloor = val; - } - double getBrightnessFloor() - { - return brightnessFloor; - } - - /** - * Sets upper cutoff for canny non-maximalizing - */ - void setCannyHighThreshold(double val) - { - cannyHighThreshold = val; - } - double getCannyHighThreshold() - { - return cannyHighThreshold; - } - - /** - * Sets the number of colors for quant multiscan - */ - void setMultiScanNrColors(int val) - { - multiScanNrColors = val; - } - int getMultiScanNrColors() - { - return multiScanNrColors; - } - - /** - * Sets whether we tile regions side-by-side or stack them - */ - void setMultiScanStack(bool val) - { - multiScanStack = val; - } - bool setMultiScanStack() - { - return multiScanStack; - } - - /** - * Sets whether we want gaussian smoothing of bitmaps before quantizing - */ - void setMultiScanSmooth(bool val) - { - multiScanSmooth = val; - } - bool getMultiScanSmooth() - { - 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 * implementing classes. Take a GdkPixbuf, trace it, and @@ -240,9 +83,6 @@ class PotraceTracingEngine : public TracingEngine std::vectortraceGrayMap(GrayMap *grayMap); - - private: - potrace_param_t *potraceParams; TraceType traceType; @@ -264,6 +104,8 @@ class PotraceTracingEngine : public TracingEngine bool multiScanStack; //do we tile or stack? bool multiScanSmooth;//do we use gaussian filter? bool multiScanRemoveBackground; //do we remove the bottom trace? + + private: /** * This is the actual wrapper of the call to Potrace. nodeCount * returns the count of nodes created. May be NULL if ignored. diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 56b0ef983..ffe1d1394 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -471,6 +471,7 @@ set ( ui_flood_and_trace_SRC tools/flood-tool.h tools/flood-tool.cpp dialog/tracedialog.cpp + dialog/tracedialog2.cpp dialog/tracedialog.h toolbar/paintbucket-toolbar.cpp toolbar/paintbucket-toolbar.h diff --git a/src/ui/dialog/tracedialog.cpp b/src/ui/dialog/tracedialog.cpp index b4190f5e1..1b9c9d4ff 100644 --- a/src/ui/dialog/tracedialog.cpp +++ b/src/ui/dialog/tracedialog.cpp @@ -12,7 +12,7 @@ * * Released under GNU GPL v2+, read the file 'COPYING' for more information. */ - +#if 0 #include "tracedialog.h" #include #include @@ -865,5 +865,5 @@ TraceDialogImpl::~TraceDialogImpl() //## E N D O F F I L E //######################################################################### - +#endif diff --git a/src/ui/dialog/tracedialog2.cpp b/src/ui/dialog/tracedialog2.cpp new file mode 100644 index 000000000..282a3db5a --- /dev/null +++ b/src/ui/dialog/tracedialog2.cpp @@ -0,0 +1,351 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** + * @file + * Bitmap tracing settings dialog - second implementation. + */ +/* Authors: + * Marc Jeanmougin + * + * Copyright (C) 2019 Authors + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "tracedialog.h" + +#include +#include +#include +#include +#include +#include + + +#include + +#include "desktop-tracker.h" +#include "desktop.h" +#include "selection.h" + +#include "inkscape.h" +#include "io/resource.h" +#include "io/sys.h" +#include "trace/autotrace/inkscape-autotrace.h" +#include "trace/potrace/inkscape-potrace.h" +#include "trace/depixelize/inkscape-depixelize.h" + + + +namespace Inkscape { +namespace UI { +namespace Dialog { + +class TraceDialogImpl2 : public TraceDialog { + public: + TraceDialogImpl2(); + ~TraceDialogImpl2() override; + + private: + Inkscape::Trace::Tracer tracer; + void traceProcess(bool do_i_trace); + void abort(); + + void previewCallback(); + void traceCallback(); + void onSelectionModified(guint flags); + void onSetDefaults(); + + void setDesktop(SPDesktop *desktop) override; + void setTargetDesktop(SPDesktop *desktop); + + SPDesktop *desktop; + DesktopTracker deskTrack; + sigc::connection desktopChangeConn; + sigc::connection selectChangedConn; + sigc::connection selectModifiedConn; + + Glib::RefPtr builder; + + Glib::RefPtr MS_scans, PA_curves, PA_islands, PA_sparse1, PA_sparse2, SS_AT_T, SS_BC_T, SS_CQ_T, + SS_CT_T, SS_ED_T, optimize, smooth, speckles; + Gtk::ComboBoxText *CBT_SS, *CBT_MS; + Gtk::CheckButton *CB_invert, *CB_MS_smooth, *CB_MS_stack, *CB_MS_rb, *CB_speckles, *CB_smooth, *CB_optimize, + /* *CB_live,*/ *CB_SIOX; + Gtk::RadioButton *RB_PA_voronoi; + Gtk::Button *B_RESET, *B_STOP, *B_OK, *B_Update; + Gtk::Box *mainBox; + Gtk::Stack *choice_scan; + Gtk::Notebook *choice_tab; + Gtk::Image *previewImage; +}; + +void TraceDialogImpl2::setDesktop(SPDesktop *desktop) +{ + Panel::setDesktop(desktop); + deskTrack.setBase(desktop); +} + +void TraceDialogImpl2::setTargetDesktop(SPDesktop *desktop) +{ + if (this->desktop != desktop) { + if (this->desktop) { + selectChangedConn.disconnect(); + selectModifiedConn.disconnect(); + } + this->desktop = desktop; + if (desktop && desktop->selection) { + selectModifiedConn = desktop->selection->connectModified( + sigc::hide<0>(sigc::mem_fun(*this, &TraceDialogImpl2::onSelectionModified))); + } + } +} + +void TraceDialogImpl2::traceProcess(bool do_i_trace) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) + desktop->setWaitingCursor(); + + if (CB_SIOX->get_active()) + tracer.enableSiox(true); + else + tracer.enableSiox(false); + + Glib::ustring type = + choice_scan->get_visible_child_name() == "SingleScan" ? CBT_SS->get_active_text() : CBT_MS->get_active_text(); + + Inkscape::Trace::Potrace::TraceType potraceType; + // Inkscape::Trace::Autotrace::TraceType autotraceType; + + bool use_autotrace = false; + + if (type == _("Brightness cutoff")) + potraceType = Inkscape::Trace::Potrace::TRACE_BRIGHTNESS; + else if (type == _("Edge detection")) + potraceType = Inkscape::Trace::Potrace::TRACE_CANNY; + else if (type == _("Color quantization")) + potraceType = Inkscape::Trace::Potrace::TRACE_QUANT; + else if (type == _("Autotrace")) + { + // autotraceType = Inkscape::Trace::Autotrace::TRACE_CENTERLINE + use_autotrace = true; + } + else if (type == _("Centerline tracing (autotrace)")) + { + // autotraceType = Inkscape::Trace::Autotrace::TRACE_CENTERLINE + use_autotrace = true; + } + else if (type == _("Brightness steps")) + potraceType = Inkscape::Trace::Potrace::TRACE_BRIGHTNESS_MULTI; + else if (type == _("Colors")) + potraceType = Inkscape::Trace::Potrace::TRACE_QUANT_COLOR; + else if (type == _("Grays")) + potraceType = Inkscape::Trace::Potrace::TRACE_QUANT_MONO; + else if (type == _("Autotrace (slower)")) + { + // autotraceType = Inkscape::Trace::Autotrace::TRACE_CENTERLINE + use_autotrace = true; + } + else + { + g_warning("Should not happen!"); + } + + Inkscape::Trace::Potrace::PotraceTracingEngine pte( + potraceType, CB_invert->get_active(), (int)SS_CQ_T->get_value(), SS_BC_T->get_value(), + 0., // Brightness floor + SS_ED_T->get_value(), (int)MS_scans->get_value(), CB_MS_stack->get_active(), CB_MS_smooth->get_active(), + CB_MS_rb->get_active()); + pte.potraceParams->opticurve = CB_optimize->get_active(); + pte.potraceParams->opttolerance = optimize->get_value(); + pte.potraceParams->alphamax = CB_smooth->get_active() ? smooth->get_value() : 0; + pte.potraceParams->turdsize = CB_speckles->get_active() ? (int)speckles->get_value() : 0; + + + + Inkscape::Trace::Autotrace::AutotraceTracingEngine ate; // TODO + Inkscape::Trace::Depixelize::DepixelizeTracingEngine dte(RB_PA_voronoi->get_active() ? Inkscape::Trace::Depixelize::TraceType::TRACE_VORONOI : Inkscape::Trace::Depixelize::TraceType::TRACE_BSPLINES, PA_curves->get_value(), (int) PA_islands->get_value(), (int) PA_sparse1->get_value(), PA_sparse2->get_value() ); + + + Glib::RefPtr pixbuf = tracer.getSelectedImage(); + if (pixbuf) { + Glib::RefPtr preview = pte.preview(pixbuf); + if (preview) { + int width = preview->get_width(); + int height = preview->get_height(); + const Gtk::Allocation &vboxAlloc = previewImage->get_allocation(); + double scaleFX = vboxAlloc.get_width() / (double)width; + double scaleFY = vboxAlloc.get_height() / (double)height; + double scaleFactor = scaleFX > scaleFY ? scaleFY : scaleFX; + int newWidth = (int)(((double)width) * scaleFactor); + int newHeight = (int)(((double)height) * scaleFactor); + Glib::RefPtr scaledPreview = preview->scale_simple(newWidth, newHeight, Gdk::INTERP_NEAREST); + // g_object_unref(preview); + previewImage->set(scaledPreview); + } + } + if (do_i_trace){ + if (choice_tab->get_current_page() == 0) + tracer.trace(&pte);//TODO + else if (choice_tab->get_current_page() == 1) + tracer.trace(&dte); + } + + if (desktop) + desktop->clearWaitingCursor(); +} + +void TraceDialogImpl2::abort() +{ /* + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) + desktop->setWaitingCursor(); + + if (mainCancelButton) + mainCancelButton->set_sensitive(false) + if (mainOkButton) + mainOkButton->set_sensitive(true); + + //### Make the abort() call to the tracer + tracer.abort(); + */ +} + +void TraceDialogImpl2::onSelectionModified(guint flags) +{ + if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG)) { + previewCallback(); + } +} + +void TraceDialogImpl2::onSetDefaults() +{ + MS_scans->set_value(8); + PA_curves->set_value(1); + PA_islands->set_value(5); + PA_sparse1->set_value(4); + PA_sparse2->set_value(1); + SS_AT_T->set_value(0); + SS_BC_T->set_value(0.45); + SS_CQ_T->set_value(64); + SS_CT_T->set_value(0); + SS_ED_T->set_value(.65); + optimize->set_value(0.2); + smooth->set_value(1); + speckles->set_value(2); + CB_invert->set_active(false); + CB_MS_smooth->set_active(true); + CB_MS_stack->set_active(true); + CB_MS_rb->set_active(false); + CB_speckles->set_active(true); + CB_smooth->set_active(true); + CB_optimize->set_active(true); + //CB_live->set_active(false); + CB_SIOX->set_active(false); +} + +void TraceDialogImpl2::previewCallback() { traceProcess(false); } +void TraceDialogImpl2::traceCallback() { traceProcess(true); } + + +TraceDialogImpl2::TraceDialogImpl2() + : TraceDialog() +{ + const std::string req_widgets[] = { "MS_scans", "PA_curves", "PA_islands", "PA_sparse1", "PA_sparse2", + "SS_AT_T", "SS_BC_T", "SS_CQ_T", "SS_CT_T", "SS_ED_T", + "optimize", "smooth", "speckles", "CB_invert", "CB_MS_smooth", + "CB_MS_stack", "CB_MS_rb", "CB_speckles", "CB_smooth", "CB_optimize", + /*"CB_live",*/ "CB_SIOX", "CBT_SS", "CBT_MS", "B_RESET", + "B_STOP", "B_OK", "mainBox", "choice_tab", "choice_scan", + "previewImage" }; + Glib::ustring gladefile = get_filename(Inkscape::IO::Resource::UIS, "dialog-trace.glade"); + try { + builder = Gtk::Builder::create_from_file(gladefile); + } catch (const Glib::Error &ex) { + g_warning("Glade file loading failed for filter effect dialog"); + return; + } + Glib::RefPtr test; + for (std::string w : req_widgets) { + test = builder->get_object(w); + if (!test) { + g_warning("Required widget %s does not exist", w.c_str()); + return; + } + } + +#define GET_O(name) \ + tmp = builder->get_object(#name); \ + name = Glib::RefPtr::cast_dynamic(tmp); + + Glib::RefPtr tmp; + +#define GET_W(name) builder->get_widget(#name, name); + GET_O(MS_scans) + GET_O(PA_curves) + GET_O(PA_islands) + GET_O(PA_sparse1) + GET_O(PA_sparse2) + GET_O(SS_AT_T) + GET_O(SS_BC_T) + GET_O(SS_CQ_T) + GET_O(SS_CT_T) + GET_O(SS_ED_T) + GET_O(optimize) + GET_O(smooth) + GET_O(speckles) + + GET_W(CB_invert) + GET_W(CB_MS_smooth) + GET_W(CB_MS_stack) + GET_W(CB_MS_rb) + GET_W(CB_speckles) + GET_W(CB_smooth) + GET_W(CB_optimize) + //GET_W(CB_live) + GET_W(CB_SIOX) + GET_W(RB_PA_voronoi) + GET_W(CBT_SS) + GET_W(CBT_MS) + GET_W(B_RESET) + GET_W(B_STOP) + GET_W(B_OK) + GET_W(B_Update) + GET_W(mainBox) + GET_W(choice_tab) + GET_W(choice_scan) + GET_W(previewImage) +#undef GET_W +#undef GET_O + _getContents()->add(*mainBox); + // show_all_children(); + desktopChangeConn = deskTrack.connectDesktopChanged(sigc::mem_fun(*this, &TraceDialogImpl2::setTargetDesktop)); + deskTrack.connect(GTK_WIDGET(gobj())); + + B_Update->signal_clicked().connect(sigc::mem_fun(*this, &TraceDialogImpl2::previewCallback)); + B_OK->signal_clicked().connect(sigc::mem_fun(*this, &TraceDialogImpl2::traceCallback)); + B_STOP->signal_clicked().connect(sigc::mem_fun(*this, &TraceDialogImpl2::abort)); + B_RESET->signal_clicked().connect(sigc::mem_fun(*this, &TraceDialogImpl2::onSetDefaults)); +} + + +TraceDialogImpl2::~TraceDialogImpl2() +{ + selectChangedConn.disconnect(); + selectModifiedConn.disconnect(); + desktopChangeConn.disconnect(); +} + + + +TraceDialog &TraceDialog::getInstance() +{ + TraceDialog *dialog = new TraceDialogImpl2(); + return *dialog; +} + + + +} // namespace Dialog +} // namespace UI +} // namespace Inkscape -- cgit v1.2.3