summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2014-03-25 11:17:41 +0000
committerJabiertxof <jtx@jtx.marker.es>2014-03-25 11:17:41 +0000
commitf86f093b618fb7747b708cf293a2e62d4c9e834f (patch)
treea521c84a52fb7222bdb37565027f9f26d51e4668 /src
parentupdate to trunk (diff)
parentUpdating libdepixelize. (diff)
downloadinkscape-f86f093b618fb7747b708cf293a2e62d4c9e834f.tar.gz
inkscape-f86f093b618fb7747b708cf293a2e62d4c9e834f.zip
update to trunk
(bzr r11950.1.313)
Diffstat (limited to 'src')
-rw-r--r--src/desktop.cpp6
-rw-r--r--src/display/nr-filter-turbulence.cpp6
-rw-r--r--src/extension/error-file.cpp2
-rw-r--r--src/extension/prefdialog.cpp4
-rw-r--r--src/libdepixelize/kopftracer2011.cpp415
-rw-r--r--src/libdepixelize/kopftracer2011.h26
-rw-r--r--src/libdepixelize/priv/homogeneoussplines.h21
-rw-r--r--src/libdepixelize/priv/pixelgraph.h80
-rw-r--r--src/libdepixelize/priv/simplifiedvoronoi.h271
-rw-r--r--src/object-snapper.cpp54
-rw-r--r--src/path-chemistry.cpp17
-rw-r--r--src/sp-object.cpp20
-rw-r--r--src/style.cpp2
-rw-r--r--src/unicoderange.cpp4
-rw-r--r--src/xml/node.h16
15 files changed, 727 insertions, 217 deletions
diff --git a/src/desktop.cpp b/src/desktop.cpp
index a02baeac8..22c00d4f1 100644
--- a/src/desktop.cpp
+++ b/src/desktop.cpp
@@ -663,8 +663,8 @@ SPDesktop::change_document (SPDocument *theDocument)
SPDesktopWidget *dtw = (SPDesktopWidget *) parent->get_data("desktopwidget");
if (dtw) {
dtw->desktop = this;
+ dtw->updateNamedview();
}
- dtw->updateNamedview();
_namedview_modified (namedview, SP_OBJECT_MODIFIED_FLAG, this);
_document_replaced_signal.emit (this, theDocument);
@@ -1537,7 +1537,9 @@ SPDesktop::updateCanvasNow()
void
SPDesktop::setDocument (SPDocument *doc)
{
- if (this->doc() && doc) {
+ if (!doc) return;
+
+ if (this->doc()) {
namedview->hide(this);
this->doc()->getRoot()->invoke_hide(dkey);
}
diff --git a/src/display/nr-filter-turbulence.cpp b/src/display/nr-filter-turbulence.cpp
index e63b335d2..a2a8c5756 100644
--- a/src/display/nr-filter-turbulence.cpp
+++ b/src/display/nr-filter-turbulence.cpp
@@ -288,7 +288,7 @@ private:
static double constexpr PerlinOffset = 4096.0;
#else
#if (__cplusplus < 201103L)
- static double const PerlinOffset = 4096.0;
+ static double const PerlinOffset;
#else
static double constexpr PerlinOffset = 4096.0;
#endif
@@ -309,6 +309,10 @@ private:
bool _fractalnoise;
};
+#if !defined(CPP11) && __cplusplus < 201103L
+ double const TurbulenceGenerator::PerlinOffset = 4096.0;
+#endif
+
FilterTurbulence::FilterTurbulence()
: gen(new TurbulenceGenerator())
, XbaseFrequency(0)
diff --git a/src/extension/error-file.cpp b/src/extension/error-file.cpp
index 5a8bede70..f60af870f 100644
--- a/src/extension/error-file.cpp
+++ b/src/extension/error-file.cpp
@@ -39,7 +39,7 @@ namespace Extension {
probably good to check anyway).
*/
ErrorFileNotice::ErrorFileNotice (void) :
- Gtk::MessageDialog::MessageDialog(
+ Gtk::MessageDialog(
"", /* message */
false, /* use markup */
Gtk::MESSAGE_WARNING, /* dialog type */
diff --git a/src/extension/prefdialog.cpp b/src/extension/prefdialog.cpp
index f3c6508af..1b657f644 100644
--- a/src/extension/prefdialog.cpp
+++ b/src/extension/prefdialog.cpp
@@ -42,9 +42,9 @@ namespace Extension {
*/
PrefDialog::PrefDialog (Glib::ustring name, gchar const * help, Gtk::Widget * controls, Effect * effect) :
#if WITH_GTKMM_3_0
- Gtk::Dialog::Dialog(_(name.c_str()), true),
+ Gtk::Dialog(_(name.c_str()), true),
#else
- Gtk::Dialog::Dialog(_(name.c_str()), true, true),
+ Gtk::Dialog(_(name.c_str()), true, true),
#endif
_help(help),
_name(name),
diff --git a/src/libdepixelize/kopftracer2011.cpp b/src/libdepixelize/kopftracer2011.cpp
index ab31d05c3..e2f387c86 100644
--- a/src/libdepixelize/kopftracer2011.cpp
+++ b/src/libdepixelize/kopftracer2011.cpp
@@ -31,7 +31,6 @@
#include <glibmm/threads.h>
#endif
-#include <utility>
#include <algorithm>
#include "kopftracer2011.h"
#include "priv/colorspace.h"
@@ -40,6 +39,11 @@
#include "priv/splines-kopf2011.h"
#include "priv/iterator.h"
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+#include <glibmm/datetime.h>
+#include <iostream>
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
namespace Tracer {
namespace Heuristics {
@@ -86,7 +90,95 @@ Splines Kopf2011::to_voronoi(const std::string &filename,
Splines Kopf2011::to_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
const Options &options)
{
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ SimplifiedVoronoi<Precision, false> voronoi
+ = _voronoi<Precision, false>(buf, options);
+
+ Glib::DateTime profiling_info[2];
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ Splines ret(voronoi);
+
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Splines construction time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+
+ return ret;
+#else // LIBDEPIXELIZE_PROFILE_KOPF2011
return Splines(_voronoi<Precision, false>(buf, options));
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+}
+
+Splines Kopf2011::to_grouped_voronoi(const std::string &filename,
+ const Options &options)
+{
+ return to_grouped_voronoi(Gdk::Pixbuf::create_from_file(filename), options);
+}
+
+Splines Kopf2011::to_grouped_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
+ const Options &options)
+{
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ SimplifiedVoronoi<Precision, false> voronoi
+ = _voronoi<Precision, false>(buf, options);
+
+ Glib::DateTime profiling_info[2];
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ HomogeneousSplines<Precision> splines(voronoi);
+
+#else // LIBDEPIXELIZE_PROFILE_KOPF2011
+ HomogeneousSplines<Precision> splines(_voronoi<Precision, false>
+ (buf, options));
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::HomogeneousSplines<" << typeid(Precision).name()
+ << ">(Tracer::SimplifiedVoronoi<" << typeid(Precision).name()
+ << ",false>) construction time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+ for ( HomogeneousSplines<Precision>::iterator it = splines.begin(),
+ end = splines.end() ; it != end ; ++it ) {
+ for ( HomogeneousSplines<Precision>::Polygon::points_iter
+ it2 = it->vertices.begin(), end2 = it->vertices.end()
+ ; it2 != end2 ; ++it2 ) {
+ it2->smooth = false;
+ }
+ for ( HomogeneousSplines<Precision>::Polygon::holes_iter
+ it2 = it->holes.begin(), end2 = it->holes.end()
+ ; it2 != end2 ; ++it2 ) {
+ for ( HomogeneousSplines<Precision>::Polygon::points_iter
+ it3 = it2->begin(), end3 = it2->end()
+ ; it3 != end3 ; ++it3 ) {
+ it3->smooth = false;
+ }
+ }
+ }
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Kopf2011::to_grouped_voronoi internal work time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ Splines ret(splines, false, options.nthreads);
+
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Splines construction time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+
+ return ret;
+#else // LIBDEPIXELIZE_PROFILE_KOPF2011
+ return Splines(splines, false, options.nthreads);
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
}
Splines Kopf2011::to_splines(const std::string &filename,
@@ -98,9 +190,36 @@ Splines Kopf2011::to_splines(const std::string &filename,
Splines Kopf2011::to_splines(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
const Options &options)
{
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ SimplifiedVoronoi<Precision, true> voronoi
+ = _voronoi<Precision, true>(buf, options);
+
+ Glib::DateTime profiling_info[2];
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ HomogeneousSplines<Precision> splines(voronoi);
+
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::HomogeneousSplines<" << typeid(Precision).name()
+ << "> construction time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ Splines ret(splines, options.optimize, options.nthreads);
+
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Splines construction time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+
+ return ret;
+#else // LIBDEPIXELIZE_PROFILE_KOPF2011
HomogeneousSplines<Precision> splines(_voronoi<Precision, true>
(buf, options));
return Splines(splines, options.optimize, options.nthreads);
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
}
template<class T, bool adjust_splines>
@@ -108,47 +227,131 @@ SimplifiedVoronoi<T, adjust_splines>
Kopf2011::_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
const Options &options)
{
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ Glib::DateTime profiling_info[2];
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
PixelGraph graph(buf);
- /*if ( !graph.width() || !graph.height() )
- return;*/
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::PixelGraph creation time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+ // gdk-pixbuf2 already checks if image size is meaningful, but asserts state
+ // preconditions and will be useful if gdk-pixbuf is replaced later
+ assert(graph.width() > 0);
+ assert(graph.height() > 0);
#ifndef NDEBUG
graph.checkConsistency();
#endif
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
// This step could be part of the initialization of PixelGraph
// and decrease the necessary number of passes
graph.connectAllNeighbors();
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::PixelGraph::connectAllNeighbors() time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
#ifndef NDEBUG
graph.checkConsistency();
#endif
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
// This step can't be part of PixelGraph initilization without adding some
// cache misses due to random access patterns that might be injected
_disconnect_neighbors_with_dissimilar_colors(graph);
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Kopf2011::"
+ "_disconnect_neighbors_with_dissimilar_colors(Tracer::PixelGraph) time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
#ifndef NDEBUG
graph.checkConsistency();
#endif
- // This and below steps must be executed in separate.
- // Otherwise, there will be colateral effects due to misassumption about the
- // data being read.
- _remove_crossing_edges_safe(graph);
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+ {
+ // edges_safe and edges_unsafe must be executed in separate.
+ // Otherwise, there will be colateral effects due to misassumption about
+ // the data being read.
+ PixelGraph::EdgePairContainer edges = graph.crossingEdges();
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::PixelGraph::crossingEdges() time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+ _remove_crossing_edges_safe(edges);
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Kopf2011::_remove_crossing_edges_safe"
+ "(Tracer::PixelGraph) time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
#ifndef NDEBUG
- graph.checkConsistency();
+ graph.checkConsistency();
#endif
- _remove_crossing_edges_unsafe(graph, options);
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+ _remove_crossing_edges_unsafe(graph, edges, options);
+ }
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Kopf2011::_remove_crossing_edges_unsafe"
+ "(Tracer::PixelGraph) time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
#ifndef NDEBUG
graph.checkConsistency();
#endif
+ assert(graph.crossingEdges().size() == 0);
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ SimplifiedVoronoi<T, adjust_splines> ret(graph);
+
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::SimplifiedVoronoi<" << typeid(T).name() << ','
+ << (adjust_splines ? "true" : "false")
+ << ">(Tracer::PixelGraph) construction time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+
+ return ret;
+#else // LIBDEPIXELIZE_PROFILE_KOPF2011
return SimplifiedVoronoi<T, adjust_splines>(graph);
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
}
// TODO: move this function (plus connectAllNeighbors) to PixelGraph constructor
@@ -192,123 +395,115 @@ Kopf2011::_disconnect_neighbors_with_dissimilar_colors(PixelGraph &graph)
*
* In this case the two diagonal connections can be safely removed without
* affecting the final result.
- *
- * \TODO: It should remember/cache who are the unsafe crossing edges?
*/
-inline void Kopf2011::_remove_crossing_edges_safe(PixelGraph &graph)
+template<class T>
+void Kopf2011::_remove_crossing_edges_safe(T &container)
{
- if ( graph.width() < 2 || graph.height() < 2 )
- return;
-
- PixelGraph::iterator it = graph.begin();
- for ( int i = 0 ; i != graph.height() - 1 ; ++i, ++it ) {
- for ( int j = 0 ; j != graph.width() - 1 ; ++j, ++it ) {
- // this <-> right
- if ( !it->adj.right )
- continue;
-
- // this <-> down
- if ( !it->adj.bottom )
- continue;
-
- PixelGraph::iterator down_right = it + graph.width() + 1;
-
- // down_right <-> right
- if ( !down_right->adj.top )
- continue;
+ for ( typename T::reverse_iterator it = container.rbegin(),
+ end = container.rend() ; it != end ; ) {
+ /* A | B
+ --+--
+ C | D */
+ PixelGraph::iterator a = it->first.first;
+ PixelGraph::iterator b = it->second.first;
+ PixelGraph::iterator c = it->second.second;
+ PixelGraph::iterator d = it->first.second;
+
+ if ( !a->adj.right || !a->adj.bottom || !b->adj.bottom
+ || !c->adj.right ) {
+ ++it;
+ continue;
+ }
- // down_right <-> down
- if ( !down_right->adj.left )
- continue;
+ // main diagonal
+ a->adj.bottomright = 0;
+ d->adj.topleft = 0;
- // main diagonal
- // this <-> down_right
- it->adj.bottomright = 0;
- down_right->adj.topleft = 0;
+ // secondary diagonal
+ b->adj.bottomleft = 0;
+ c->adj.topright = 0;
- // secondary diagonal
- // right <-> down
- (it + 1)->adj.bottomleft = 0;
- (it + graph.width())->adj.topright = 0;
- }
+ // base iterator is always past one
+ typename T::iterator current = --(it.base());
+ ++it;
+ container.erase(current);
}
}
/**
* This method removes crossing edges using the heuristics.
*/
-inline
-void Kopf2011::_remove_crossing_edges_unsafe(PixelGraph &graph,
+template<class T>
+void Kopf2011::_remove_crossing_edges_unsafe(PixelGraph &graph, T &edges,
const Options &options)
{
- if ( graph.width() < 2 || graph.height() < 2 )
- return;
-
- // Iterate over the graph, 2x2 blocks at time
- PixelGraph::iterator it = graph.begin();
- for (int i = 0 ; i != graph.height() - 1 ; ++i, ++it ) {
- for ( int j = 0 ; j != graph.width() - 1 ; ++j, ++it ) {
- using std::pair;
- using std::make_pair;
-
- typedef pair<PixelGraph::iterator, PixelGraph::iterator> Edge;
- typedef pair<Edge, int> EdgeWeight;
-
- EdgeWeight diagonals[2] = {
- make_pair(make_pair(it, graph.nodeBottomRight(it)), 0),
- make_pair(make_pair(graph.nodeRight(it), graph.nodeBottom(it)),
- 0)
- };
-
- // Check if there are crossing edges
- if ( !diagonals[0].first.first->adj.bottomright
- || !diagonals[1].first.first->adj.bottomleft ) {
- continue;
- }
-
- // Compute weights
- for ( int i = 0 ; i != 2 ; ++i ) {
- // Curves and islands heuristics
- PixelGraph::const_iterator a = diagonals[i].first.first;
- PixelGraph::const_iterator b = diagonals[i].first.second;
-
- diagonals[i].second += Heuristics::curves(graph, a, b)
- * options.curvesMultiplier;
-
- diagonals[i].second += Heuristics::islands(a, b)
- * options.islandsWeight;
- }
-
- {
- // Sparse pixels heuristic
- Heuristics::SparsePixels sparse_pixels;
-
- for ( int i = 0 ; i != 2 ; ++i )
- sparse_pixels.diagonals[i] = diagonals[i];
-
- sparse_pixels(graph, options.sparsePixelsRadius);
-
- for ( int i = 0 ; i != 2 ; ++i ) {
- diagonals[i].second += sparse_pixels.diagonals[i].second
- * options.sparsePixelsMultiplier;
- }
- }
+ std::vector< std::pair<int, int> > weights(edges.size(),
+ std::make_pair(0, 0));
+
+ // Compute weights
+ for ( typename T::size_type i = 0 ; i != edges.size() ; ++i ) {
+ /* A | B
+ --+--
+ C | D */
+ PixelGraph::iterator a = edges[i].first.first;
+ PixelGraph::iterator b = edges[i].second.first;
+ PixelGraph::iterator c = edges[i].second.second;
+ PixelGraph::iterator d = edges[i].first.second;
+
+ // Curves heuristic
+ weights[i].first += Heuristics::curves(graph, a, d)
+ * options.curvesMultiplier;
+ weights[i].second += Heuristics::curves(graph, b, c)
+ * options.curvesMultiplier;
+
+ // Islands heuristic
+ weights[i].first += Heuristics::islands(a, d) * options.islandsWeight;
+ weights[i].second += Heuristics::islands(b, c) * options.islandsWeight;
+
+ // Sparse pixels heuristic
+ using Heuristics::SparsePixels;
+ SparsePixels sparse_pixels;
+
+ sparse_pixels.diagonals[SparsePixels::MAIN_DIAGONAL].first
+ = edges[i].first;
+ sparse_pixels.diagonals[SparsePixels::SECONDARY_DIAGONAL].first
+ = edges[i].second;
+
+ sparse_pixels(graph, options.sparsePixelsRadius);
+
+ weights[i].first
+ += sparse_pixels.diagonals[SparsePixels::MAIN_DIAGONAL].second
+ * options.sparsePixelsMultiplier;
+ weights[i].second
+ += sparse_pixels.diagonals[SparsePixels::SECONDARY_DIAGONAL].second
+ * options.sparsePixelsMultiplier;
+ }
- // Remove edges with lower weight
- if ( diagonals[0].second > diagonals[1].second ) {
- diagonals[1].first.first->adj.bottomleft = 0;
- diagonals[1].first.second->adj.topright = 0;
- } else if ( diagonals[0].second < diagonals[1].second ) {
- diagonals[0].first.first->adj.bottomright = 0;
- diagonals[0].first.second->adj.topleft = 0;
- } else {
- diagonals[0].first.first->adj.bottomright = 0;
- diagonals[0].first.second->adj.topleft = 0;
- diagonals[1].first.first->adj.bottomleft = 0;
- diagonals[1].first.second->adj.topright = 0;
- }
+ // Remove edges with lower weight
+ for ( typename T::size_type i = 0 ; i != edges.size() ; ++i ) {
+ /* A | B
+ --+--
+ C | D */
+ PixelGraph::iterator a = edges[i].first.first;
+ PixelGraph::iterator b = edges[i].second.first;
+ PixelGraph::iterator c = edges[i].second.second;
+ PixelGraph::iterator d = edges[i].first.second;
+
+ if ( weights[i].first > weights[i].second ) {
+ b->adj.bottomleft = 0;
+ c->adj.topright = 0;
+ } else if ( weights[i].first < weights[i].second ) {
+ a->adj.bottomright = 0;
+ d->adj.topleft = 0;
+ } else {
+ a->adj.bottomright = 0;
+ b->adj.bottomleft = 0;
+ c->adj.topright = 0;
+ d->adj.topleft = 0;
}
}
+
+ edges.clear();
}
inline int Heuristics::curves(const PixelGraph &graph,
diff --git a/src/libdepixelize/kopftracer2011.h b/src/libdepixelize/kopftracer2011.h
index c224abe9a..598f6c79c 100644
--- a/src/libdepixelize/kopftracer2011.h
+++ b/src/libdepixelize/kopftracer2011.h
@@ -88,6 +88,23 @@ public:
/**
* # Exceptions
*
+ * \p options.optimize and options.nthreads will be ignored
+ *
+ * Glib::FileError
+ * Gdk::PixbufError
+ */
+ static Splines to_grouped_voronoi(const std::string &filename,
+ const Options &options = Options());
+
+ /*
+ * \p options.optimize and options.nthreads will be ignored
+ */
+ static Splines to_grouped_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
+ const Options &options = Options());
+
+ /**
+ * # Exceptions
+ *
* Glib::FileError
* Gdk::PixbufError
*/
@@ -106,8 +123,13 @@ private:
const Options &options);
static void _disconnect_neighbors_with_dissimilar_colors(PixelGraph &graph);
- static void _remove_crossing_edges_safe(PixelGraph &graph);
- static void _remove_crossing_edges_unsafe(PixelGraph &graph,
+
+ // here, T/template is only used as an easy way to not expose internal
+ // symbols
+ template<class T>
+ static void _remove_crossing_edges_safe(T &container);
+ template<class T>
+ static void _remove_crossing_edges_unsafe(PixelGraph &graph, T &edges,
const Options &options);
};
diff --git a/src/libdepixelize/priv/homogeneoussplines.h b/src/libdepixelize/priv/homogeneoussplines.h
index 57c77a163..6c4894dd8 100644
--- a/src/libdepixelize/priv/homogeneoussplines.h
+++ b/src/libdepixelize/priv/homogeneoussplines.h
@@ -38,6 +38,12 @@ class HomogeneousSplines
public:
struct Polygon
{
+ typedef std::vector< Point<T> > Points;
+ typedef typename Points::iterator points_iter;
+ typedef typename Points::const_iterator const_points_iter;
+ typedef typename std::vector<Points>::iterator holes_iter;
+ typedef typename std::vector<Points>::const_iterator const_holes_iter;
+
Polygon() {}
Polygon(const guint8 (&rgba)[4])
{
@@ -59,7 +65,8 @@ public:
typedef typename std::vector<Polygon>::const_iterator const_iterator;
typedef typename std::vector<Polygon>::size_type size_type;
- HomogeneousSplines(const SimplifiedVoronoi<T> &voronoi);
+ template<bool adjust_splines>
+ HomogeneousSplines(const SimplifiedVoronoi<T, adjust_splines> &voronoi);
// Iterators
iterator begin()
@@ -98,12 +105,7 @@ public:
}
private:
- typedef typename SimplifiedVoronoi<T>::Cell Cell;
typedef std::vector< Point<T> > Points;
-
- typedef typename SimplifiedVoronoi<T>::iterator voronoi_iter;
- typedef typename SimplifiedVoronoi<T>::const_iterator voronoi_citer;
-
typedef typename Points::iterator points_iter;
typedef typename Points::const_iterator points_citer;
typedef typename Points::reverse_iterator points_riter;
@@ -171,7 +173,9 @@ private:
};
template<class T>
-HomogeneousSplines<T>::HomogeneousSplines(const SimplifiedVoronoi<T> &voronoi) :
+template<bool adjust_splines>
+HomogeneousSplines<T>::HomogeneousSplines(const SimplifiedVoronoi<T,
+ adjust_splines> &voronoi) :
_width(voronoi.width()),
_height(voronoi.height())
{
@@ -179,6 +183,9 @@ HomogeneousSplines<T>::HomogeneousSplines(const SimplifiedVoronoi<T> &voronoi) :
// return;
using colorspace::same_color;
+ typedef typename SimplifiedVoronoi<T, adjust_splines>::const_iterator
+ voronoi_citer;
+
// Identify visible edges (group polygons with the same color)
for ( voronoi_citer cell_it = voronoi.begin(), cell_end = voronoi.end()
; cell_it != cell_end ; ++cell_it ) {
diff --git a/src/libdepixelize/priv/pixelgraph.h b/src/libdepixelize/priv/pixelgraph.h
index 9e8c2124a..112242647 100644
--- a/src/libdepixelize/priv/pixelgraph.h
+++ b/src/libdepixelize/priv/pixelgraph.h
@@ -28,6 +28,7 @@
#include <gdkmm/pixbuf.h>
#include <vector>
#include <cassert>
+#include <utility>
namespace Tracer {
@@ -76,6 +77,10 @@ public:
typedef std::vector<Node>::reverse_iterator reverse_iterator;
typedef std::vector<Node>::const_reverse_iterator const_reverse_iterator;
+ typedef std::pair<iterator, iterator> Edge;
+ typedef std::pair<Edge, Edge> EdgePair;
+ typedef std::vector<EdgePair> EdgePairContainer;
+
class ColumnView
{
public:
@@ -162,6 +167,7 @@ public:
// Algorithms
void connectAllNeighbors();
+ EdgePairContainer crossingEdges();
int toX(const_iterator n) const
{
@@ -389,14 +395,23 @@ inline void PixelGraph::connectAllNeighbors()
// ...then the "top" nodes...
if ( _width > 2 ) {
Node *it = &_nodes[1];
- for ( int i = 1 ; i != _width - 1 ; ++i ) {
- it->adj.right = 1;
- it->adj.bottomright = 1;
- it->adj.bottom = 1;
- it->adj.bottomleft = 1;
- it->adj.left = 1;
+ if ( _height > 1 ) {
+ for ( int i = 1 ; i != _width - 1 ; ++i ) {
+ it->adj.right = 1;
+ it->adj.bottomright = 1;
+ it->adj.bottom = 1;
+ it->adj.bottomleft = 1;
+ it->adj.left = 1;
- ++it;
+ ++it;
+ }
+ } else {
+ for ( int i = 1 ; i != _width - 1 ; ++i ) {
+ it->adj.right = 1;
+ it->adj.left = 1;
+
+ ++it;
+ }
}
}
@@ -417,14 +432,23 @@ inline void PixelGraph::connectAllNeighbors()
// ...then the "left" nodes...
if ( _height > 2 ) {
iterator it = nodeBottom(begin()); // [0][1]
- for ( int i = 1 ; i != _height - 1 ; ++i ) {
- it->adj.top = 1;
- it->adj.topright = 1;
- it->adj.right = 1;
- it->adj.bottomright = 1;
- it->adj.bottom = 1;
+ if ( _width > 1 ) {
+ for ( int i = 1 ; i != _height - 1 ; ++i ) {
+ it->adj.top = 1;
+ it->adj.topright = 1;
+ it->adj.right = 1;
+ it->adj.bottomright = 1;
+ it->adj.bottom = 1;
- it = nodeBottom(it);
+ it = nodeBottom(it);
+ }
+ } else {
+ for ( int i = 1 ; i != _height - 1 ; ++i ) {
+ it->adj.top = 1;
+ it->adj.bottom = 1;
+
+ it = nodeBottom(it);
+ }
}
}
@@ -482,6 +506,34 @@ inline void PixelGraph::connectAllNeighbors()
}
}
+PixelGraph::EdgePairContainer PixelGraph::crossingEdges()
+{
+ EdgePairContainer ret;
+
+ if ( width() < 2 || height() < 2 )
+ return ret;
+
+ // Iterate over the graph, 2x2 blocks at time
+ PixelGraph::iterator it = begin();
+ for (int i = 0 ; i != height() - 1 ; ++i, ++it ) {
+ for ( int j = 0 ; j != width() - 1 ; ++j, ++it ) {
+ EdgePair diagonals(
+ Edge(it, nodeBottomRight(it)),
+ Edge(nodeRight(it), nodeBottom(it)));
+
+ // Check if there are crossing edges
+ if ( !diagonals.first.first->adj.bottomright
+ || !diagonals.second.first->adj.bottomleft ) {
+ continue;
+ }
+
+ ret.push_back(diagonals);
+ }
+ }
+
+ return ret;
+}
+
inline PixelGraph::Node &PixelGraph::ColumnView::operator[](int line)
{
return _nodes[line * _width + _column];
diff --git a/src/libdepixelize/priv/simplifiedvoronoi.h b/src/libdepixelize/priv/simplifiedvoronoi.h
index 8a25bc626..84feab08d 100644
--- a/src/libdepixelize/priv/simplifiedvoronoi.h
+++ b/src/libdepixelize/priv/simplifiedvoronoi.h
@@ -296,21 +296,40 @@ SimplifiedVoronoi<T, adjust_splines>
PixelGraph::const_iterator graph_it = graph.begin() + 1;
Cell *cells_it = &_cells.front() + 1;
- for ( int i = 1 ; i != _width - 1 ; ++i, ++graph_it, ++cells_it ) {
- for ( int j = 0 ; j != 4 ; ++j )
- cells_it->rgba[j] = graph_it->rgba[j];
+ if ( _height > 1 ) {
+ for ( int i = 1 ; i != _width - 1 ; ++i, ++graph_it, ++cells_it ) {
+ for ( int j = 0 ; j != 4 ; ++j )
+ cells_it->rgba[j] = graph_it->rgba[j];
- // Top-left
- cells_it->vertices.push_back(Point<T>(i, 0, false));
+ // Top-left
+ cells_it->vertices.push_back(Point<T>(i, 0, false));
- // Top-right
- cells_it->vertices.push_back(Point<T>(i + 1, 0, false));
+ // Top-right
+ cells_it->vertices.push_back(Point<T>(i + 1, 0, false));
- // Bottom-right
- _complexBottomRight(graph, graph_it, cells_it, i, 0);
+ // Bottom-right
+ _complexBottomRight(graph, graph_it, cells_it, i, 0);
- // Bottom-left
- _complexBottomLeft(graph, graph_it, cells_it, i, 0);
+ // Bottom-left
+ _complexBottomLeft(graph, graph_it, cells_it, i, 0);
+ }
+ } else {
+ for ( int i = 1 ; i != _width - 1 ; ++i, ++graph_it, ++cells_it ) {
+ for ( int j = 0 ; j != 4 ; ++j )
+ cells_it->rgba[j] = graph_it->rgba[j];
+
+ // Top-left
+ cells_it->vertices.push_back(Point<T>(i, 0, false));
+
+ // Top-right
+ cells_it->vertices.push_back(Point<T>(i + 1, 0, false));
+
+ // Bottom-right
+ cells_it->vertices.push_back(Point<T>(i + 1, 1, false));
+
+ // Bottom-left
+ cells_it->vertices.push_back(Point<T>(i, 1, false));
+ }
}
}
@@ -344,24 +363,46 @@ SimplifiedVoronoi<T, adjust_splines>
PixelGraph::const_iterator graph_it = graph.begin() + _width;
Cell *cells_it = &_cells.front() + _width;
- for ( int i = 1 ; i != _height - 1 ; ++i) {
- for ( int j = 0 ; j != 4 ; ++j )
- cells_it->rgba[j] = graph_it->rgba[j];
+ if ( _width > 1 ) {
+ for ( int i = 1 ; i != _height - 1 ; ++i) {
+ for ( int j = 0 ; j != 4 ; ++j )
+ cells_it->rgba[j] = graph_it->rgba[j];
- // Top-left
- cells_it->vertices.push_back(Point<T>(0, i, false));
+ // Top-left
+ cells_it->vertices.push_back(Point<T>(0, i, false));
- // Top-right
- _complexTopRight(graph, graph_it, cells_it, 0, i);
+ // Top-right
+ _complexTopRight(graph, graph_it, cells_it, 0, i);
- // Bottom-right
- _complexBottomRight(graph, graph_it, cells_it, 0, i);
+ // Bottom-right
+ _complexBottomRight(graph, graph_it, cells_it, 0, i);
- // Bottom-left
- cells_it->vertices.push_back(Point<T>(0, i + 1, false));
+ // Bottom-left
+ cells_it->vertices.push_back(Point<T>(0, i + 1, false));
- graph_it += _width;
- cells_it += _width;
+ graph_it += _width;
+ cells_it += _width;
+ }
+ } else {
+ for ( int i = 1 ; i != _height - 1 ; ++i) {
+ for ( int j = 0 ; j != 4 ; ++j )
+ cells_it->rgba[j] = graph_it->rgba[j];
+
+ // Top-left
+ cells_it->vertices.push_back(Point<T>(0, i, false));
+
+ // Top-right
+ cells_it->vertices.push_back(Point<T>(1, i, false));
+
+ // Bottom-right
+ cells_it->vertices.push_back(Point<T>(1, i, false));
+
+ // Bottom-left
+ cells_it->vertices.push_back(Point<T>(0, i + 1, false));
+
+ graph_it += _width;
+ cells_it += _width;
+ }
}
}
@@ -890,7 +931,11 @@ SimplifiedVoronoi<T, adjust_splines>
}
if ( !smooth[0] && adjust_splines ) {
- cells_it->vertices.push_back(vertices[0].invisible());
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
+ cells_it->vertices.push_back(vertices[0].invisible());
+#else
+ cells_it->vertices.push_back(vertices[0]);
+#endif
{
Point<T> another = vertices[0];
transform(another,
@@ -899,7 +944,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
- ( 0.5625
- ( topright(a_it) + topleft(b_it) ) * 0.1875 ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertices[0];
@@ -910,7 +959,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( 0.1875
- ( topright(a_it) + topleft(b_it) ) * 0.0625) );
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertices[0];
@@ -920,7 +973,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
0.0625
+ ( bottomright(b_it) - topright(d_it) ) * 0.0625);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
transform(vertices[0],
@@ -932,7 +989,9 @@ SimplifiedVoronoi<T, adjust_splines>
+ ( topright(d_it) - topright(a_it)
- topleft(b_it) - bottomright(b_it) )
* 0.03125 ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertices[0].visible = false;
+#endif
}
}
@@ -950,7 +1009,11 @@ SimplifiedVoronoi<T, adjust_splines>
0.0625
+ ( bottomleft(a_it) - bottomleft(d_it)
- topleft(c_it) - bottomright(c_it) ) * 0.03125);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertices[1];
@@ -960,7 +1023,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
0.1875
- ( bottomright(c_it) + bottomleft(d_it) ) * 0.0625);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertices[1];
@@ -973,7 +1040,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( bottomleft(a_it) - topleft(c_it) )
* 0.0625 ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertices[1];
@@ -985,9 +1056,15 @@ SimplifiedVoronoi<T, adjust_splines>
- ( 0.1875
- ( bottomleft(a_it) - topleft(c_it) )
* 0.1875 ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertices[1].visible = false;
+#endif
}
cells_it->vertices.push_back(vertices[1]);
@@ -1029,13 +1106,21 @@ SimplifiedVoronoi<T, adjust_splines>
- ( ( bottomright(c_it) + topleft(c_it) )
* 0.03125 );
transform(another, - amount, amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * bottomright(c_it);
transform(another, amount, 0.25 - amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1043,16 +1128,26 @@ SimplifiedVoronoi<T, adjust_splines>
transform(another, - ( 0.25 - amount ),
- amount);
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.1875 * topleft(c_it);
transform(another, - ( 0.75 - amount ),
- amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
} else if ( twin_is_contour ) {
T amount = 0.125
- ( ( bottomleft(d_it) + topright(d_it) )
@@ -1076,7 +1171,11 @@ SimplifiedVoronoi<T, adjust_splines>
- amount
* ( topleft(c_it) + topright(d_it)
- bottomleft(a_it) - bottomright(b_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1087,7 +1186,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
- amount
* ( topright(d_it) - bottomright(b_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1099,7 +1202,11 @@ SimplifiedVoronoi<T, adjust_splines>
- amount
* ( topleft(c_it) - bottomleft(a_it) ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1110,9 +1217,15 @@ SimplifiedVoronoi<T, adjust_splines>
// y
- amount
* ( topleft(c_it) - bottomleft(a_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
} else {
// {this, right} is the pair with the angle
@@ -1146,13 +1259,21 @@ SimplifiedVoronoi<T, adjust_splines>
if ( !vertex.smooth ) {
if ( another_is_contour ) {
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(vertex.invisible());
+#else
+ cells_it->vertices.push_back(vertex);
+#endif
{
Point<T> another = vertex;
T amount = 0.1875 * topleft(b_it);
transform(another, - amount,
- ( 0.75 - amount ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1160,20 +1281,30 @@ SimplifiedVoronoi<T, adjust_splines>
transform(another, - amount,
- ( 0.25 - amount ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * bottomright(b_it);
transform(another, 0.25 - amount, amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
T amount = 0.125
- (bottomright(b_it) + topleft(b_it))
* 0.03125;
transform(vertex, amount, - amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
} else if ( twin_is_contour ) {
T amount = 0.125
@@ -1187,7 +1318,11 @@ SimplifiedVoronoi<T, adjust_splines>
// I REALLY NEED lambdas to improve this code without
// creating yet another interface that takes a million
// of function parameters and keep code locality
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(vertex.invisible());
+#else
+ cells_it->vertices.push_back(vertex);
+#endif
{
Point<T> another = vertex;
T amount = 0.1875;
@@ -1197,7 +1332,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( 0.75
- ( topleft(b_it) + topright(a_it) )
* amount ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1209,7 +1348,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( topleft(b_it) + topright(a_it) )
* amount ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1219,7 +1362,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
0.25 - amount
* ( bottomleft(d_it) + bottomright(c_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
transform(vertex,
@@ -1230,7 +1377,9 @@ SimplifiedVoronoi<T, adjust_splines>
( topleft(b_it) - bottomleft(d_it)
+ topright(a_it) - bottomright(c_it) )
* 0.03125);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
}
} else {
@@ -1273,28 +1422,46 @@ SimplifiedVoronoi<T, adjust_splines>
- ( topleft(c_it) + bottomright(c_it) )
* 0.03125;
transform(another, - amount, amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * bottomright(c_it);
transform(another, amount, 0.25 - amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * topleft(c_it);
transform(another, - ( 0.25 - amount ), - amount);
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.1875 * topleft(c_it);
transform(another, - ( 0.75 - amount ), - amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
} else {
special = true;
}
@@ -1308,7 +1475,11 @@ SimplifiedVoronoi<T, adjust_splines>
}
if ( special ) {
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(vertex.invisible());
+#else
+ cells_it->vertices.push_back(vertex);
+#endif
{
Point<T> another = vertex;
T amount = 0.1875;
@@ -1318,7 +1489,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( 0.75
- ( topleft(b_it) + topright(a_it) )
* amount ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1330,7 +1505,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( topleft(b_it) + topright(a_it) )
* amount ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1340,7 +1519,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
0.25 - amount
* ( bottomleft(d_it) + bottomright(c_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
transform(vertex,
@@ -1351,7 +1534,9 @@ SimplifiedVoronoi<T, adjust_splines>
( topleft(b_it) - bottomleft(d_it)
+ topright(a_it) - bottomright(c_it) )
* 0.03125);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
}
} else if ( right(c_it) && adjust_splines ) {
@@ -1372,31 +1557,49 @@ SimplifiedVoronoi<T, adjust_splines>
if ( !vertex.smooth ) {
if ( similar_neighbor_is_contour ) {
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(vertex.invisible());
+#else
+ cells_it->vertices.push_back(vertex);
+#endif
{
Point<T> another = vertex;
T amount = 0.1875 * topleft(b_it);
transform(another, - amount, - ( 0.75 - amount ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * topleft(b_it);
transform(another, - amount, - ( 0.25 - amount ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * bottomright(b_it);
transform(another, 0.25 - amount, amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
T amount = 0.125
- 0.03125 * (topleft(b_it) + bottomright(b_it));
transform(vertex, amount, - amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
} else {
special = true;
@@ -1422,7 +1625,11 @@ SimplifiedVoronoi<T, adjust_splines>
- amount
* ( topleft(c_it) + topright(d_it)
- bottomleft(a_it) - bottomright(b_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1433,7 +1640,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
- amount
* ( topright(d_it) - bottomright(b_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1445,7 +1656,11 @@ SimplifiedVoronoi<T, adjust_splines>
- amount
* ( topleft(c_it) - bottomleft(a_it) ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1456,9 +1671,15 @@ SimplifiedVoronoi<T, adjust_splines>
// y
- amount
* ( topleft(c_it) - bottomleft(a_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
} else {
// there is a 4-color pattern, where the current node
diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp
index de50f0dd8..3b8956bc8 100644
--- a/src/object-snapper.cpp
+++ b/src/object-snapper.cpp
@@ -119,35 +119,35 @@ void Inkscape::ObjectSnapper::_findCandidates(SPObject* parent,
_findCandidates(obj, it, false, bbox_to_snap, true, item->i2doc_affine());
}
}
- }
- if (SP_IS_GROUP(o)) {
- _findCandidates(o, it, false, bbox_to_snap, clip_or_mask, additional_affine);
- } else {
- Geom::OptRect bbox_of_item;
- Preferences *prefs = Preferences::get();
- int prefs_bbox = prefs->getBool("/tools/bounding_box", 0);
- // We'll only need to obtain the visual bounding box if the user preferences tell
- // us to, AND if we are snapping to the bounding box itself. If we're snapping to
- // paths only, then we can just as well use the geometric bounding box (which is faster)
- SPItem::BBoxType bbox_type = (!prefs_bbox && _snapmanager->snapprefs.isTargetSnappable(SNAPTARGET_BBOX_CATEGORY)) ?
- SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX;
- if (clip_or_mask) {
- // Oh oh, this will get ugly. We cannot use sp_item_i2d_affine directly because we need to
- // insert an additional transformation in document coordinates (code copied from sp_item_i2d_affine)
- bbox_of_item = item->bounds(bbox_type, item->i2doc_affine() * additional_affine * dt->doc2dt());
+ if (SP_IS_GROUP(o)) {
+ _findCandidates(o, it, false, bbox_to_snap, clip_or_mask, additional_affine);
} else {
- bbox_of_item = item->desktopBounds(bbox_type);
- }
- if (bbox_of_item) {
- // See if the item is within range
- if (bbox_to_snap_incl.intersects(*bbox_of_item)
- || (_snapmanager->snapprefs.isTargetSnappable(SNAPTARGET_ROTATION_CENTER) && bbox_to_snap_incl.contains(item->getCenter()))) { // rotation center might be outside of the bounding box
- // This item is within snapping range, so record it as a candidate
- _candidates->push_back(SnapCandidateItem(item, clip_or_mask, additional_affine));
- // For debugging: print the id of the candidate to the console
- // SPObject *obj = (SPObject*)item;
- // std::cout << "Snap candidate added: " << obj->getId() << std::endl;
+ Geom::OptRect bbox_of_item;
+ Preferences *prefs = Preferences::get();
+ int prefs_bbox = prefs->getBool("/tools/bounding_box", 0);
+ // We'll only need to obtain the visual bounding box if the user preferences tell
+ // us to, AND if we are snapping to the bounding box itself. If we're snapping to
+ // paths only, then we can just as well use the geometric bounding box (which is faster)
+ SPItem::BBoxType bbox_type = (!prefs_bbox && _snapmanager->snapprefs.isTargetSnappable(SNAPTARGET_BBOX_CATEGORY)) ?
+ SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX;
+ if (clip_or_mask) {
+ // Oh oh, this will get ugly. We cannot use sp_item_i2d_affine directly because we need to
+ // insert an additional transformation in document coordinates (code copied from sp_item_i2d_affine)
+ bbox_of_item = item->bounds(bbox_type, item->i2doc_affine() * additional_affine * dt->doc2dt());
+ } else {
+ bbox_of_item = item->desktopBounds(bbox_type);
+ }
+ if (bbox_of_item) {
+ // See if the item is within range
+ if (bbox_to_snap_incl.intersects(*bbox_of_item)
+ || (_snapmanager->snapprefs.isTargetSnappable(SNAPTARGET_ROTATION_CENTER) && bbox_to_snap_incl.contains(item->getCenter()))) { // rotation center might be outside of the bounding box
+ // This item is within snapping range, so record it as a candidate
+ _candidates->push_back(SnapCandidateItem(item, clip_or_mask, additional_affine));
+ // For debugging: print the id of the candidate to the console
+ // SPObject *obj = (SPObject*)item;
+ // std::cout << "Snap candidate added: " << obj->getId() << std::endl;
+ }
}
}
}
diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp
index 5f478435d..22928ccdd 100644
--- a/src/path-chemistry.cpp
+++ b/src/path-chemistry.cpp
@@ -83,10 +83,10 @@ sp_selected_path_combine(SPDesktop *desktop)
gint position = 0;
char const *id = NULL;
char const *transform = NULL;
- gchar *style = NULL;
- gchar *path_effect = NULL;
+ Glib::ustring style;
+ Glib::ustring path_effect;
- SPCurve* curve = 0;
+ SPCurve* curve = NULL;
SPItem *first = NULL;
Inkscape::XML::Node *parent = NULL;
@@ -114,18 +114,15 @@ sp_selected_path_combine(SPDesktop *desktop)
id = first->getRepr()->attribute("id");
transform = first->getRepr()->attribute("transform");
// FIXME: merge styles of combined objects instead of using the first one's style
- style = g_strdup(first->getRepr()->attribute("style"));
- path_effect = g_strdup(first->getRepr()->attribute("inkscape:path-effect"));
+ style = first->getRepr()->attribute("style");
+ path_effect = first->getRepr()->attribute("inkscape:path-effect");
//c->transform(item->transform);
curve = c;
} else {
c->transform(item->getRelativeTransform(first));
curve->append(c, false);
c->unref();
- }
- // unless this is the topmost object,
- if (item != first) {
// reduce position only if the same parent
if (item->getRepr()->parent() == parent) {
position--;
@@ -150,15 +147,13 @@ sp_selected_path_combine(SPDesktop *desktop)
repr->setAttribute("transform", transform);
}
repr->setAttribute("style", style);
- g_free(style);
repr->setAttribute("inkscape:path-effect", path_effect);
- g_free(path_effect);
// set path data corresponding to new curve
gchar *dstring = sp_svg_write_path(curve->get_pathvector());
curve->unref();
- if (path_effect) {
+ if (!path_effect.empty()) {
repr->setAttribute("inkscape:original-d", dstring);
} else {
repr->setAttribute("d", dstring);
diff --git a/src/sp-object.cpp b/src/sp-object.cpp
index 764b5f260..be3a1ab9d 100644
--- a/src/sp-object.cpp
+++ b/src/sp-object.cpp
@@ -967,31 +967,29 @@ static gchar const *sp_xml_get_space_string(unsigned int space)
}
Inkscape::XML::Node* SPObject::write(Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) {
- SPObject* object = this;
-
if (!repr && (flags & SP_OBJECT_WRITE_BUILD)) {
- repr = object->getRepr()->duplicate(doc);
+ repr = this->getRepr()->duplicate(doc);
if (!( flags & SP_OBJECT_WRITE_EXT )) {
repr->setAttribute("inkscape:collect", NULL);
}
- } else {
- repr->setAttribute("id", object->getId());
+ } else if (repr) {
+ repr->setAttribute("id", this->getId());
- if (object->xml_space.set) {
+ if (this->xml_space.set) {
char const *xml_space;
- xml_space = sp_xml_get_space_string(object->xml_space.value);
+ xml_space = sp_xml_get_space_string(this->xml_space.value);
repr->setAttribute("xml:space", xml_space);
}
if ( flags & SP_OBJECT_WRITE_EXT &&
- object->collectionPolicy() == SPObject::ALWAYS_COLLECT )
+ this->collectionPolicy() == SPObject::ALWAYS_COLLECT )
{
repr->setAttribute("inkscape:collect", "always");
} else {
repr->setAttribute("inkscape:collect", NULL);
}
- SPStyle const *const obj_style = object->style;
+ SPStyle const *const obj_style = this->style;
if (obj_style) {
gchar *s = sp_style_write_string(obj_style, SP_STYLE_FLAG_IFSET);
@@ -1028,7 +1026,7 @@ Inkscape::XML::Node* SPObject::write(Inkscape::XML::Document *doc, Inkscape::XML
g_warning("Item's style is NULL; repr style attribute is %s", style_str);
}
- /** \note We treat object->style as authoritative. Its effects have
+ /** \note We treat this->style as authoritative. Its effects have
* been written to the style attribute above; any properties that are
* unset we take to be deliberately unset (e.g. so that clones can
* override the property).
@@ -1038,7 +1036,7 @@ Inkscape::XML::Node* SPObject::write(Inkscape::XML::Document *doc, Inkscape::XML
* possibly we should write property attributes instead of a style
* attribute.
*/
- sp_style_unset_property_attrs (object);
+ sp_style_unset_property_attrs (this);
}
return repr;
diff --git a/src/style.cpp b/src/style.cpp
index c57cf6349..bc869b127 100644
--- a/src/style.cpp
+++ b/src/style.cpp
@@ -3677,7 +3677,7 @@ sp_style_read_itextdecoration(SPITextDecorationLine *line, SPITextDecorationStyl
int slen = str - hstr;
gchar *frag = g_strndup(hstr,slen+1); // only send one piece at a time, since keywords may be intermixed
sp_style_read_itextdecorationColor(color, frag);
- free(frag);
+ g_free(frag);
if(color->set)break;
if(*str == '\0')break;
hstr = str + 1;
diff --git a/src/unicoderange.cpp b/src/unicoderange.cpp
index 803e1a884..5a9c4b331 100644
--- a/src/unicoderange.cpp
+++ b/src/unicoderange.cpp
@@ -39,7 +39,7 @@ int UnicodeRange::add_range(gchar* val){
while(val[i]!='\0' && val[i]!='-' && val[i]!=' ' && val[i]!=','){
i++;
}
- r.start = (gchar*) malloc((i+1)*sizeof(gchar*));
+ r.start = (gchar*) malloc((i+1)*sizeof(gchar));
strncpy(r.start, val, i);
r.start[i] = '\0';
val+=i;
@@ -48,7 +48,7 @@ int UnicodeRange::add_range(gchar* val){
if (val[0]=='-'){
val++;
while(val[i]!='\0' && val[i]!='-' && val[i]!=' ' && val[i]!=',') i++;
- r.end = (gchar*) malloc((i+1)*sizeof(gchar*));
+ r.end = (gchar*) malloc((i+1)*sizeof(gchar));
strncpy(r.end, val, i);
r.end[i] = '\0';
// val+=i;
diff --git a/src/xml/node.h b/src/xml/node.h
index e83d8a7b7..c1977b0a8 100644
--- a/src/xml/node.h
+++ b/src/xml/node.h
@@ -19,6 +19,7 @@
#define SEEN_INKSCAPE_XML_NODE_H
#include <glibmm/value.h>
+#include <glibmm/ustring.h>
#include "gc-anchored.h"
#include "util/list.h"
@@ -194,6 +195,7 @@ public:
*/
virtual void setContent(gchar const *value)=0;
+ //@{
/**
* @brief Change an attribute of this node
*
@@ -204,7 +206,19 @@ public:
* @param is_interactive Ignored
*/
virtual void setAttribute(gchar const *key, gchar const *value, bool is_interactive=false)=0;
-
+
+ void setAttribute(char const *key, Glib::ustring const &value, bool is_interactive=false)
+ {
+ setAttribute(key, value.empty() ? NULL : value.c_str(), is_interactive);
+ }
+
+ void setAttribute(Glib::ustring const &key, Glib::ustring const &value, bool is_interactive=false)
+ {
+ setAttribute( key.empty() ? NULL : key.c_str(),
+ value.empty() ? NULL : value.c_str(), is_interactive);
+ }
+ //@}
+
/**
* @brief Directly set the integer GQuark code for the name of the node
*