From 619f8b5d9173f2bcc9d9aefccee832d686724e79 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 17 Oct 2016 15:04:09 +0200 Subject: Add option to scale mesh to fit in bounding box. (bzr r15173) --- src/sp-mesh-array.cpp | 44 +++++++++++++++++++++++++++++ src/sp-mesh-array.h | 10 +++++++ src/ui/tools/mesh-tool.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++ src/ui/tools/mesh-tool.h | 1 + src/widgets/mesh-toolbar.cpp | 19 +++++++++++++ src/widgets/toolbox.cpp | 1 + 6 files changed, 141 insertions(+) (limited to 'src') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 042800fbf..208dac2bc 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -51,6 +51,7 @@ #include "sp-mesh-row.h" #include "sp-mesh-patch.h" #include "sp-stop.h" +#include "display/curve.h" // For new mesh creation #include "preferences.h" @@ -2699,6 +2700,49 @@ void SPMeshNodeArray::update_handles( guint corner, std::vector< guint > /*selec } +SPCurve * SPMeshNodeArray::outline_path() { + + SPCurve *outline = new SPCurve(); + + outline->moveto( nodes[0][0]->p ); + + int ncol = nodes[0].size(); + int nrow = nodes.size(); + + // Top + for (int i = 1; i < ncol; i += 3 ) { + outline->curveto( nodes[0][i]->p, nodes[0][i+1]->p, nodes[0][i+2]->p); + } + + // Right + for (int i = 1; i < nrow; i += 3 ) { + outline->curveto( nodes[i][ncol-1]->p, nodes[i+1][ncol-1]->p, nodes[i+2][ncol-1]->p); + } + + // Bottom (right to left) + for (int i = 1; i < nrow; i += 3 ) { + outline->curveto( nodes[nrow-1][ncol-i-1]->p, nodes[nrow-1][ncol-i-2]->p, nodes[nrow-1][ncol-i-3]->p); + } + + // Left (bottom to top) + for (int i = 1; i < nrow; i += 3 ) { + outline->curveto( nodes[nrow-i-1][0]->p, nodes[nrow-i-2][0]->p, nodes[nrow-i-3][0]->p); + } + + outline->closepath(); + + return outline; +} + +void SPMeshNodeArray::transform(Geom::Affine const &m) { + + for (int i = 0; i < nodes[0].size(); ++i) { + for (int j = 0; j < nodes.size(); ++j) { + nodes[j][i]->p *= m; + } + } +} + // Defined in gradient-chemistry.cpp guint32 average_color(guint32 c1, guint32 c2, gdouble p); diff --git a/src/sp-mesh-array.h b/src/sp-mesh-array.h index 49ee88e53..2ba1bfd5d 100644 --- a/src/sp-mesh-array.h +++ b/src/sp-mesh-array.h @@ -141,6 +141,7 @@ public: }; class SPMeshGradient; +class SPCurve; // An array of mesh nodes. class SPMeshNodeArray { @@ -195,6 +196,15 @@ public: // Update other nodes in response to a node move. void update_handles( unsigned int corner, std::vector< unsigned int > selected_corners, Geom::Point old_p, MeshNodeOperation op ); + // Return outline path (don't forget to unref() when done with curve) + SPCurve * outline_path(); + + // Transform array + void transform(Geom::Affine const &m); + + // Find bounding box + // Geom::OptRect findBoundingBox(); + void split_row( unsigned int i, unsigned int n ); void split_column( unsigned int j, unsigned int n ); void split_row( unsigned int i, double coord ); diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp index 33cdc3bda..cea508782 100644 --- a/src/ui/tools/mesh-tool.cpp +++ b/src/ui/tools/mesh-tool.cpp @@ -52,6 +52,7 @@ #include "ui/tools/mesh-tool.h" #include "sp-mesh-gradient.h" #include "display/sp-ctrlcurve.h" +#include "display/curve.h" using Inkscape::DocumentUndo; @@ -430,6 +431,71 @@ sp_mesh_context_corner_operation (MeshTool *rc, MeshCornerOperation operation ) } +/** + * Scale mesh to just fit into bbox of selected items. + */ +void +sp_mesh_context_fit_mesh_in_bbox (MeshTool *rc) +{ + +#ifdef DEBUG_MESH + std::cout << "sp_mesh_context_fit_mesh_in_bbox: entrance: Entrance"<< std::endl; +#endif + + SPDesktop *desktop = SP_EVENT_CONTEXT (rc)->desktop; + + Inkscape::Selection *selection = desktop->getSelection(); + if (selection == NULL) { + return; + } + + bool changed = false; + auto itemlist = selection->items(); + for (auto i=itemlist.begin(); i!=itemlist.end(); ++i) { + + SPItem *item = *i; + SPStyle *style = item->style; + + if (style && (style->fill.isPaintserver())) { + SPPaintServer *server = item->style->getFillPaintServer(); + if ( SP_IS_MESHGRADIENT(server) ) { + + SPMeshGradient *gradient = SP_MESHGRADIENT(server); + SPCurve * outline = gradient->array.outline_path(); + Geom::OptRect mesh_bbox = outline->get_pathvector().boundsExact(); + outline->unref(); + Geom::OptRect item_bbox = item->geometricBounds(); + + if ((*mesh_bbox).width() == 0) { + continue; + } + if ((*mesh_bbox).height() == 0) { + continue; + } + double scale_x = (*item_bbox).width() /(*mesh_bbox).width() ; + double scale_y = (*item_bbox).height()/(*mesh_bbox).height(); + + Geom::Translate t1(-(*mesh_bbox).min()); + Geom::Scale scale(scale_x,scale_y); + Geom::Translate t2((*item_bbox).min()); + Geom::Affine transform = t1 * scale * t2; + if (!transform.isIdentity() ) { + gradient->array.transform(transform); + gradient->array.write( gradient ); + gradient->requestModified(SP_OBJECT_MODIFIED_FLAG); + changed = true; + } + } + } + + } + if (changed) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH, + _("Fit mesh inside bounding box.")); + } +} + + /** Handles all keyboard and mouse input for meshs. Note: node/handle events are take care of elsewhere. diff --git a/src/ui/tools/mesh-tool.h b/src/ui/tools/mesh-tool.h index 91b35b3af..f142bfd9c 100644 --- a/src/ui/tools/mesh-tool.h +++ b/src/ui/tools/mesh-tool.h @@ -59,6 +59,7 @@ private: void sp_mesh_context_select_next(ToolBase *event_context); void sp_mesh_context_select_prev(ToolBase *event_context); void sp_mesh_context_corner_operation(MeshTool *event_context, MeshCornerOperation operation ); +void sp_mesh_context_fit_mesh_in_bbox(MeshTool *event_context); } } diff --git a/src/widgets/mesh-toolbar.cpp b/src/widgets/mesh-toolbar.cpp index 0e689fee0..898104ad3 100644 --- a/src/widgets/mesh-toolbar.cpp +++ b/src/widgets/mesh-toolbar.cpp @@ -348,6 +348,14 @@ static void ms_pick_colors(void) } } +static void ms_fit_mesh(void) +{ + MeshTool *mt = get_mesh_tool(); + if (mt) { + sp_mesh_context_fit_mesh_in_bbox( mt ); + } +} + static void mesh_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); /** @@ -557,6 +565,17 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj } + { + InkAction* act = ink_action_new( "MeshFitInBoundingBoxAction", + _("Scale mesh to bounding box:"), + _("Scale mesh to fit inside bounding box."), + INKSCAPE_ICON("mesh-gradient-fit"), + secondarySize ); + g_object_set( act, "short_label", _("Fit mesh"), NULL ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_fit_mesh), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + } static void mesh_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index c03ca85e6..d3715cf4e 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -572,6 +572,7 @@ static gchar const * ui_descr = " " " " " " + " " " " " " " " -- cgit v1.2.3 From 5a528acc28fee968aee4d79373625ed7d0fa553d Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 18 Oct 2016 19:07:20 +0200 Subject: Use geometric bounding box for fill, visual for stroke in creating mesh. (bzr r15175) --- src/ui/tools/mesh-tool.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp index cea508782..c6983b94a 100644 --- a/src/ui/tools/mesh-tool.cpp +++ b/src/ui/tools/mesh-tool.cpp @@ -1036,7 +1036,8 @@ static void sp_mesh_new_default(MeshTool &rc) { // Get corresponding object SPMeshGradient *mg = static_cast(document->getObjectByRepr(repr)); - mg->array.create(mg, *i, (*i)->visualBounds()); + mg->array.create(mg, *i, (fill_or_stroke == Inkscape::FOR_FILL) ? + (*i)->geometricBounds() : (*i)->visualBounds()); bool isText = SP_IS_TEXT(*i); sp_style_set_property_url (*i, ((fill_or_stroke == Inkscape::FOR_FILL) ? "fill":"stroke"), @@ -1045,6 +1046,11 @@ static void sp_mesh_new_default(MeshTool &rc) { (*i)->requestModified(SP_OBJECT_MODIFIED_FLAG|SP_OBJECT_STYLE_MODIFIED_FLAG); } + if (css) { + sp_repr_css_attr_unref(css); + css = 0; + } + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH, _("Create mesh")); // status text; we do not track coords because this branch is run once, not all the time -- cgit v1.2.3 From 1277a92d4c1cd93e9a172718f557a8cd1a855625 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Wed, 19 Oct 2016 00:24:26 +0200 Subject: update author list in about dialog from AUTHORS file (bzr r15176) --- src/ui/dialog/aboutbox.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index 04cf9d02a..846f00d8a 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -256,6 +256,7 @@ void AboutBox::initStrings() { "Joshua L. Blocher\n" "Hanno Böck\n" "Tomasz Boczkowski\n" +"Adrian Boguszewski\n" "Henrik Bohre\n" "Boldewyn\n" "Daniel Borgmann\n" @@ -265,6 +266,7 @@ void AboutBox::initStrings() { "Christopher Brown\n" "Marcus Brubaker\n" "Luca Bruno\n" +"Brynn (brynn@inkscapecommunity.com)\n" "Nicu Buculei\n" "Bulia Byak\n" "Pierre Caclin\n" @@ -289,10 +291,12 @@ void AboutBox::initStrings() { "Nicolas Dufour\n" "Tim Dwyer\n" "Maxim V. Dziumanenko\n" +"Moritz Eberl\n" "Johan Engelen\n" "Miklos Erdelyi\n" "Ulf Erikson\n" "Noé Falzon\n" +"Sebastian Faubel\n" "Frank Felfe\n" "Andrew Fitzsimon\n" "Edward Flick\n" @@ -324,6 +328,7 @@ void AboutBox::initStrings() { "Jean-Olivier Irisson\n" "Bob Jamison\n" "Ted Janeczko\n" +"Marc Jeanmougin\n" "jEsuSdA\n" "Fernando Lucchesi Bastos Jurema\n" "Lauris Kaplinski\n" @@ -389,6 +394,7 @@ void AboutBox::initStrings() { "Shivaken\n" "Michael Sloan\n" "John Smith\n" +"Sandra Snan\n" "Boštjan Špetič\n" "Aaron Spike\n" "Kaushik Sridharan\n" @@ -413,7 +419,8 @@ void AboutBox::initStrings() { "Gellule Xg\n" "Daniel Yacob\n" "Masatake Yamato\n" -"David Yip"; +"David Yip" +; //############################## //# T R A N S L A T O R S -- cgit v1.2.3