diff options
| -rw-r--r-- | share/icons/icons.svg | 16 | ||||
| -rw-r--r-- | src/sp-mesh-array.cpp | 44 | ||||
| -rw-r--r-- | src/sp-mesh-array.h | 10 | ||||
| -rw-r--r-- | src/ui/tools/mesh-tool.cpp | 66 | ||||
| -rw-r--r-- | src/ui/tools/mesh-tool.h | 1 | ||||
| -rw-r--r-- | src/widgets/mesh-toolbar.cpp | 19 | ||||
| -rw-r--r-- | src/widgets/toolbox.cpp | 1 |
7 files changed, 151 insertions, 6 deletions
diff --git a/share/icons/icons.svg b/share/icons/icons.svg index 4a65cd3f1..5ceaac9bb 100644 --- a/share/icons/icons.svg +++ b/share/icons/icons.svg @@ -2509,7 +2509,7 @@ http://www.inkscape.org/</dc:description> <g id="paint-pattern" transform="translate(395.0006,254)" inkscape:label="#fill_pattern"> <rect inkscape:label="#ccc" y="66" x="671" height="18" width="18" id="rect4541" style="color:#000000;fill:#99b6d4;fill-rule:evenodd;stroke-width:1.0000004" /> <path style="fill:#ffffff;stroke:#000000;stroke-width:0;stroke-linejoin:round" d="M 676.7274,66.00001 673.4547,69.42858 677.5456,73.7143 681.6365,69.42858 678.3638,66.00001 676.7274,66.00001 Z M 681.6365,69.42858 685.7274,73.7143 689.0001,70.28572 689.0001,68.57144 686.5456,66.00001 684.9092,66.00001 681.6365,69.42858 Z M 685.7274,73.7143 681.6365,78.00001 685.7274,82.28573 689.0001,78.85715 689.0001,77.14287 685.7274,73.7143 Z M 685.7274,82.28573 684.091,84.00001 687.3638,84.00001 685.7274,82.28573 Z M 681.6365,78.00001 677.5456,73.7143 673.4547,78.00001 677.5456,82.28573 681.6365,78.00001 Z M 677.5456,82.28573 675.9092,84.00001 679.1819,84.00001 677.5456,82.28573 Z M 673.4547,78.00001 671.0001,75.42858 671.0001,80.57144 673.4547,78.00001 Z M 673.4547,69.42858 671.0001,66.85715 671.0001,72.00001 673.4547,69.42858 Z" id="rect4545" inkscape:connector-curvature="0" /> -<rect style="color:#000000;fill:none;stroke:#000000;stroke-width:0.9999989;stroke-linecap:round;stroke-linejoin:round" id="rect4381" width="19.00081" height="18.99999" x="670.4994" y="65.5" /> +<rect style="color:#000000;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round" id="rect4381" width="19" height="19" x="670.4994" y="65.5" /> </g> <g id="paint-swatch" transform="translate(395.0006,282)" inkscape:label="#fill_swatch"> <rect inkscape:label="#ccc" y="66" x="671" height="18" width="18" id="rect11473" style="color:#000000;fill:#99b6d4;fill-rule:evenodd;stroke-width:1.0000004" /> @@ -3950,11 +3950,11 @@ http://www.inkscape.org/</dc:description> <use transform="matrix(1,0,0,0.99644,-1.2735,13.06755)" xlink:href="#rect3568" id="use3137" x="0" y="0" width="100%" height="100%" /> </g> <g id="paint-gradient-mesh" inkscape:label="#fill_mesh"> -<rect style="fill:#99b6d4" height="9.5" width="9.5" y="347" x="1095.5" id="rect3140" /> -<rect style="fill:#ffffff" height="9.5" width="9.5" y="357" x="1095.5" id="rect3142" /> -<rect style="fill:#99b6d4" height="9.5" width="9.5" y="357" x="1105" id="rect3144" /> -<rect style="fill:#ffffff" height="9.5" width="9.5" y="347" x="1105" id="rect3146" /> -<use xlink:href="#rect4381" transform="translate(425.0351,282.0202)" id="use3148" x="0" y="0" width="100%" height="100%" /> +<rect style="fill:#99b6d4" height="9.5" width="9.5" y="347.5" x="1095.5" id="rect3140" /> +<rect style="fill:#ffffff" height="9.5" width="9.5" y="357" x="1095.5" id="rect3142" /> +<rect style="fill:#99b6d4" height="9.5" width="9.5" y="357" x="1105" id="rect3144" /> +<rect style="fill:#ffffff" height="9.5" width="9.5" y="347.5" x="1105" id="rect3146" /> +<use xlink:href="#rect4381" transform="translate(425,282)" id="use3148" x="0" y="0" width="100%" height="100%" /> </g> <g id="paint-gradient-conical" inkscape:label="#fill_conical"> <path sodipodi:rx="9.5" sodipodi:ry="9.5" style="fill:#ffffff" sodipodi:type="arc" sodipodi:start="0" sodipodi:cy="357" sodipodi:cx="1135" sodipodi:end="1.047198" d="M 1144.5,357 A 9.5,9.5 0 0 1 1139.75,365.2272 L 1135,357 Z" id="path3145" /> @@ -3965,6 +3965,10 @@ http://www.inkscape.org/</dc:description> <path sodipodi:rx="9.5" sodipodi:ry="9.5" style="fill:#99b6d4" sodipodi:type="arc" d="M 1139.75,348.7728 A 9.5,9.5 0 0 1 1144.5,357 L 1135,357 Z" sodipodi:cy="357" sodipodi:cx="1135" sodipodi:end="6.283185" sodipodi:start="5.235988" id="path3155" /> <circle style="fill:none;stroke:#000000" id="path3157" cx="1135" cy="357" r="9.5" /> </g> +<g id="mesh-gradient-fit" inkscape:label="#mesh-gradient-fit"> +<path style="fill:#99b6d4;stroke:none" d="m 1172,350 c 6,6 -4,10 0,14 -6,6 -10,-4 -14,0 -6,-6 4,-10 0,-14 6,-6 10,4 14,0 z"/> +<rect style="fill:none;stroke:#000000;stroke-linejoin:round" id="outline" width="19" height="19" x="1155.5" y="347.5" /> +</g> <g id="dialog-filters" inkscape:label="#dialog-filters"> <path sodipodi:nodetypes="cscccccc" inkscape:connector-curvature="0" id="path7138" d="M 272.415,308.6281 C 272.509,305.3138 278.0595,305.1187 279.875,305.1077 281.8707,305.0957 287.2213,305.3694 287.3348,308.5442 L 281.3157,314.8308 281.3157,319.0217 C 279.8863,319.4867 279.7151,319.5463 278.3661,319.0217 L 278.3661,314.8308 Z" style="opacity:0.909;fill:url(#linearGradient7163);stroke:#000000;stroke-width:0.9143469;stroke-linecap:round;stroke-linejoin:round;stroke-dashoffset:10" /> <ellipse id="path7140" style="opacity:0.909;fill:url(#radialGradient7218);stroke:url(#radialGradient7220);stroke-width:3.5711801;stroke-linecap:round;stroke-linejoin:round;stroke-dashoffset:10" transform="matrix(0.115021,0,0,0.1903986,253.0723,212.7017)" cx="234.355" cy="496.273" rx="60.6092" ry="14.6472" /> 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; @@ -431,6 +432,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 = " <toolitem action='MeshToggleSidesAction' />" " <toolitem action='MeshMakeEllipticalAction' />" " <toolitem action='MeshPickColorsAction' />" + " <toolitem action='MeshFitInBoundingBoxAction' />" " <separator />" " <toolitem action='MeshWarningAction' />" " <toolitem action='MeshSmoothAction' />" |
