From 1b7079f62b7c2bfe454e20bae3776a7e36e7e684 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 9 Oct 2016 20:37:54 +0200 Subject: Provide simple "preview" for mesh gradients. (bzr r15157) --- src/sp-gradient.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) (limited to 'src/sp-gradient.cpp') diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp index d3e38485b..333316697 100644 --- a/src/sp-gradient.cpp +++ b/src/sp-gradient.cpp @@ -46,6 +46,7 @@ #include "sp-radial-gradient.h" #include "sp-mesh-gradient.h" #include "sp-mesh-row.h" +#include "sp-mesh-patch.h" #include "sp-stop.h" /// Has to be power of 2 Seems to be unused. @@ -229,8 +230,6 @@ SPGradient::SPGradient() : SPPaintServer(), units(), state(2), vector() { - this->has_patches = 0; - this->ref = new SPGradientReference(this); this->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(SPGradient::gradientRefChanged), this)); @@ -250,6 +249,7 @@ SPGradient::SPGradient() : SPPaintServer(), units(), this->spread_set = FALSE; this->has_stops = FALSE; + this->has_patches = FALSE; this->vector.built = false; this->vector.stops.clear(); @@ -275,6 +275,17 @@ void SPGradient::build(SPDocument *document, Inkscape::XML::Node *repr) this->has_stops = TRUE; break; } + if (SP_IS_MESHROW(&ochild)) { + for (auto& ochild2: ochild.children) { + if (SP_IS_MESHPATCH(&ochild2)) { + this->has_patches = TRUE; + break; + } + } + if (this->has_patches == TRUE) { + break; + } + } } this->readAttr( "gradientUnits" ); @@ -470,6 +481,9 @@ void SPGradient::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *re } } } + if ( ochild && SP_IS_MESHROW(ochild) ) { + this->has_patches = TRUE; + } /// \todo Fixme: should we schedule "modified" here? this->requestModified(SP_OBJECT_MODIFIED_FLAG); @@ -485,11 +499,23 @@ void SPGradient::remove_child(Inkscape::XML::Node *child) SPPaintServer::remove_child(child); this->has_stops = FALSE; + this->has_patches = FALSE; for (auto& ochild: children) { if (SP_IS_STOP(&ochild)) { this->has_stops = TRUE; break; } + if (SP_IS_MESHROW(&ochild)) { + for (auto& ochild2: ochild.children) { + if (SP_IS_MESHPATCH(&ochild2)) { + this->has_patches = TRUE; + break; + } + } + if (this->has_patches == TRUE) { + break; + } + } } if ( this->getStopCount() == 0 ) { @@ -765,6 +791,14 @@ static bool has_stopsFN(SPGradient const *gr) return gr->hasStops(); } +/** + * True if gradient has patches (i.e. a mesh). + */ +static bool has_patchesFN(SPGradient const *gr) +{ + return gr->hasPatches(); +} + /** * True if gradient has spread set. */ @@ -793,6 +827,16 @@ SPGradient *SPGradient::getVector(bool force_vector) return src; } +SPGradient *SPGradient::getArray(bool force_vector) +{ + SPGradient * src = chase_hrefs(this, has_patchesFN); + + // if (force_vector) { + // src = sp_gradient_ensure_vector_normalized(src); + // } + return src; +} + /** * Returns the effective spread of given gradient (climbing up the refs chain if needed). * @@ -1031,6 +1075,7 @@ void SPGradient::rebuildArray() } array.read( SP_MESHGRADIENT( this ) ); + has_patches = array.patch_columns() > 0; } Geom::Affine @@ -1132,6 +1177,20 @@ sp_gradient_create_preview_pattern(SPGradient *gr, double width) cairo_pattern_add_color_stop_rgba(pat, i->offset, i->color.v.c[0], i->color.v.c[1], i->color.v.c[2], i->opacity); } + } else { + + // For the moment, use the top row of nodes for preview. + unsigned columns = gr->array.patch_columns(); + + double offset = 1.0/double(columns); + + pat = cairo_pattern_create_linear(0, 0, width, 0); + + for (unsigned i = 0; i < columns+1; ++i) { + SPMeshNode* node = gr->array.node( 0, i*3 ); + cairo_pattern_add_color_stop_rgba(pat, i*offset, + node->color.v.c[0], node->color.v.c[1], node->color.v.c[2], node->opacity); + } } return pat; -- cgit v1.2.3