diff --git a/src/helper/geom-pathvector_nodesatellites.cpp b/src/helper/geom-pathvector_nodesatellites.cpp index 42867b9fa6f69bc006332809a79acc258a1d22de..ce6b18ade634c746cda5de40b8ec7e31d80e071e 100644 --- a/src/helper/geom-pathvector_nodesatellites.cpp +++ b/src/helper/geom-pathvector_nodesatellites.cpp @@ -220,7 +220,7 @@ void PathVectorNodeSatellites::recalculateForNewPathVector(Geom::PathVector cons if (!_nodesatellites.empty() && !_nodesatellites[k].empty()) { assert(countnodes == _nodesatellites[k].size()); for (size_t l = 0; l < countcurves; ++l) { - if (Geom::are_near(_pathvector[k][l].initialPoint(), pathv[i][j].initialPoint())) { + if (Geom::are_near(_pathvector[k][l].initialPoint(), pathv[i][j].initialPoint(), 0.001)) { // epsilon is not enought big path_nodesatellites.push_back(_nodesatellites[k][l]); found = true; break; diff --git a/src/live_effects/fill-conversion.cpp b/src/live_effects/fill-conversion.cpp index f772ee8dd4d67f1bfab738ad6849f6d2f5cc6b1a..4d8c11560fca9d6481c3782bb9d2e7087ecdda7a 100644 --- a/src/live_effects/fill-conversion.cpp +++ b/src/live_effects/fill-conversion.cpp @@ -188,6 +188,7 @@ void lpe_shape_convert_stroke_and_fill(SPShape *shape) void lpe_shape_revert_stroke_and_fill(SPShape *shape, double width) { + // width is in pixels, if use in a LPE with other units convert before use SPObject *linked = get_linked_fill(shape); SPCSSAttr *css = sp_repr_css_attr_new(); @@ -210,13 +211,18 @@ void lpe_shape_revert_stroke_and_fill(SPShape *shape, double width) } else { sp_repr_css_set_property(css, "fill", "none"); } - - Glib::ustring display_unit = shape->document->getDisplayUnit()->abbr.c_str(); - width = Inkscape::Util::Quantity::convert(width, display_unit.c_str(), "px"); Inkscape::CSSOStringStream os; os << fabs(width); sp_repr_css_set_property(css, "stroke-width", os.str().c_str()); - + // Reverse affine by desktop style apply. + { + Geom::Affine const local(shape->i2doc_affine()); + double const ex(local.descrim()); + if ( ( ex != 0. ) + && ( ex != 1. ) ) { + sp_css_attr_scale(css, ex); + } + } sp_desktop_apply_css_recursive(shape, css, true); sp_repr_css_attr_unref(css); } diff --git a/src/live_effects/lpe-dashed-stroke.cpp b/src/live_effects/lpe-dashed-stroke.cpp index 7edbeacdaafd60adcf9b727ee404a8e92d26ea65..49f5390b09d9594a32856b37b7aa3f24a8ed17a5 100644 --- a/src/live_effects/lpe-dashed-stroke.cpp +++ b/src/live_effects/lpe-dashed-stroke.cpp @@ -30,6 +30,8 @@ LPEDashedStroke::LPEDashedStroke(LivePathEffectObject *lpeobject) registerParameter(&halfextreme); registerParameter(&unifysegment); registerParameter(&message); + + message.write_to_SVG(); // resert old legacy uneeded data numberdashes.param_set_range(2, 999999999); numberdashes.param_set_increments(1, 1); numberdashes.param_set_digits(0); diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 505099d24293e1e0b18876edb0ab8724a162873f..ff578bf3740cf88263c958e4f5779c4c48b0091c 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -102,30 +102,32 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) item->removeCurrentPathEffect(false); } auto rect = cast(splpeitem); - SPDocument *document = getSPDoc(); - Glib::ustring display_unit = document->getDisplayUnit()->abbr.c_str(); Geom::PathVector pathv = pathv_to_linear_and_cubic_beziers(shape->curve()->get_pathvector()); + double power = radius; + double a = 0; if (rect) { double a = rect->getVisibleRx(); a = std::max(a, rect->getVisibleRy()); - rect->setVisibleRx(0); - rect->setVisibleRy(0); - pathv = Geom::PathVector(Geom::Path(rect->getRect())); - if (!Geom::are_near(a,0)) { - a *= rect->i2doc_affine().inverse().descrim(); - a = Inkscape::Util::Quantity::convert(a, display_unit.c_str(), unit.get_abbreviation()); - radius.param_set_value(a); + if (a) { + rect->setRx(true, 0); + rect->setRy(true, 0); + pathv = Geom::PathVector(Geom::Path(rect->getRect())); + if (!Geom::are_near(a, 0)) { + a /= getSPDoc()->getDocumentScale()[Geom::X]; + unit.param_set_value(getSPDoc()->getWidth().unit->abbr.c_str()); + flexible.param_setValue(false); + radius.param_set_value(a); + power = a; + } } } NodeSatellites nodesatellites; - double power = radius; - - if (!flexible) { - SPDocument *document = getSPDoc(); - Glib::ustring display_unit = document->getDisplayUnit()->abbr.c_str(); - power = Inkscape::Util::Quantity::convert(power, unit.get_abbreviation(), display_unit.c_str()); + if (!flexible && Geom::are_near(a, 0)) { + auto trans = lpeItem->transform.inverse(); + power = Inkscape::Util::Quantity::convert(power, unit.get_abbreviation(), "px") / getSPDoc()->getDocumentScale()[Geom::X]; + power *= ((trans.expansionX() + trans.expansionY()) / 2.0); } NodeSatelliteType nodesatellite_type = FILLET; @@ -149,9 +151,6 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) nodesatellite.setHasMirror(true); nodesatellite.setHidden(hide_knots); _pathvector_nodesatellites->recalculateForNewPathVector(pathv, nodesatellite); - - - nodesatellites_param.setPathVectorNodeSatellites(_pathvector_nodesatellites); } @@ -234,9 +233,13 @@ void LPEFilletChamfer::updateAmount() setSelected(_pathvector_nodesatellites); double power = radius; if (!flexible) { - SPDocument *document = getSPDoc(); - Glib::ustring display_unit = document->getDisplayUnit()->abbr.c_str(); - power = Inkscape::Util::Quantity::convert(power, unit.get_abbreviation(), display_unit.c_str()); + power = Inkscape::Util::Quantity::convert(power, unit.get_abbreviation(), "px") / getSPDoc()->getDocumentScale()[Geom::X]; + std::vector lpeitems = getCurrrentLPEItems(); + if (lpeitems.size() == 1) { + sp_lpe_item = lpeitems[0]; + auto trans = sp_lpe_item->transform.inverse(); + power *= ((trans.expansionX() + trans.expansionY()) / 2.0); + } } _pathvector_nodesatellites->updateAmount(power, apply_no_radius, apply_with_radius, only_selected, use_knot_distance, flexible); @@ -347,9 +350,7 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) if (is_load || number_nodes != previous_number_nodes) { double power = radius; if (!flexible) { - SPDocument *document = getSPDoc(); - Glib::ustring display_unit = document->getDisplayUnit()->abbr.c_str(); - power = Inkscape::Util::Quantity::convert(power, unit.get_abbreviation(), display_unit.c_str()); + power = Inkscape::Util::Quantity::convert(power, unit.get_abbreviation(), "px") / getSPDoc()->getDocumentScale()[Geom::X]; } NodeSatelliteType nodesatellite_type = FILLET; std::map gchar_map_to_nodesatellite_type = boost::assign::map_list_of( @@ -376,11 +377,6 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) nodesatellites_param.reloadKnots(); } } - Glib::ustring current_unit = unit.get_abbreviation(); - if (previous_unit != current_unit && previous_unit != "") { - updateAmount(); - } - previous_unit = std::move(current_unit); } else { g_warning("LPE Fillet can only be applied to shapes (not groups)."); } diff --git a/src/live_effects/lpe-measure-segments.cpp b/src/live_effects/lpe-measure-segments.cpp index fdf8c2aec6899be5ecfa26c8e9c7d5b09b98da8c..74f94fb10a71d799abe7ac9d272b5008a5babfca 100644 --- a/src/live_effects/lpe-measure-segments.cpp +++ b/src/live_effects/lpe-measure-segments.cpp @@ -80,7 +80,7 @@ LPEMeasureSegments::LPEMeasureSegments(LivePathEffectObject *lpeobject) : text_top_bottom(_("Label position"), _("Distance of the labels from the dimension line"), "text_top_bottom", &wr, this, 0), helpline_distance(_("Help line distance"), _("Distance of the perpendicular lines from the path"), "helpline_distance", &wr, this, 0.0), helpline_overlap(_("Help line elongation"), _("Distance of the perpendicular lines' ends from the dimension line"), "helpline_overlap", &wr, this, 2.0), - line_width(_("Line width"), _("Dimension line width. DIN standard: 0.25 or 0.35 mm"), "line_width", &wr, this, 0.25), + line_width(_("Line width"), _("Dimension line width in mm. DIN standard: 0.25 or 0.35 mm"), "line_width", &wr, this, 0.25), scale(_("Scale"), _("Scaling factor"), "scale", &wr, this, 1.0), // TRANSLATORS: Don't translate "{measure}" and "{unit}" variables. @@ -98,7 +98,7 @@ LPEMeasureSegments::LPEMeasureSegments(LivePathEffectObject *lpeobject) : // active for 1.1 smallx100(_("Multiply values < 1"), _("Multiply values smaller than 1 by 100 and leave out the unit"), "smallx100", &wr, this, false), linked_items(_("Linked objects:"), _("Objects whose nodes are projected onto the path and generate new measurements"), "linked_items", &wr, this, true), - distance_projection(_("Distance"), _("Distance of the dimension lines from the outermost node"), "distance_projection", &wr, this, 20.0), + distance_projection(_("Distance"), _("Distance of the dimension lines from the outermost node (mm)"), "distance_projection", &wr, this, 20.0), angle_projection(_("Angle of projection"), _("Angle of projection in 90° steps"), "angle_projection", &wr, this, 0.0), active_projection(_("Activate projection"), _("Activate projection mode"), "active_projection", &wr, this, false), avoid_overlapping(_("Avoid label overlap"), _("Rotate labels if the segment is shorter than the label"), "avoid_overlapping", &wr, this, true), @@ -193,21 +193,6 @@ LPEMeasureSegments::LPEMeasureSegments(LivePathEffectObject *lpeobject) : fontsize = 0; rgb32 = 0; arrow_gap = 0; - //TODO: add newlines for 1.1 (not easy) - helpdata.param_update_default(_("General\n" - "Display and position dimension lines and labels\n\n" - "Projection\n" - "Show a line with measurements based on the selected items\n\n" - "Options\n" - "Options for color, precision, label formatting and display\n\n" - "Tips\n" - "Custom styling: To further customize the styles, " - "use the XML editor to find out the class or ID, then use the " - "Style dialog to apply a new style.\n" - "Blacklists: allow to hide some segments or projection steps.\n" - "Multiple Measure LPEs: In the same object, in conjunction with blacklists," - "this allows for labels and measurements with different orientations or additional projections.\n" - "Set Defaults: For every LPE, default values can be set at the bottom.")); } Gtk::Widget * @@ -370,7 +355,7 @@ LPEMeasureSegments::createArrowMarker(Glib::ustring mode) } void -LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double length, Geom::Coord angle, bool remove, bool valid) +LPEMeasureSegments::createTextLabel(Geom::Point &pos, size_t counter, double length, Geom::Coord angle, bool remove, bool valid) { SPDocument *document = getSPDoc(); if (!document || !sp_lpe_item || !sp_lpe_item->getId()) { @@ -453,7 +438,11 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng rtspan->setAttributeOrRemoveIfEmpty("style", css_str); rtspan->removeAttribute("transform"); sp_repr_css_attr_unref (css); - length = Inkscape::Util::Quantity::convert(length, display_unit.c_str(), unit.get_abbreviation()); + if (legacy) { + length = Inkscape::Util::Quantity::convert(length, document->getDisplayUnit()->abbr.c_str(), unit.get_abbreviation()); + } else { + length = Inkscape::Util::Quantity::convert(length, "px", unit.get_abbreviation()) * getSPDoc()->getDocumentScale()[Geom::X]; + } if (local_locale) { setlocale (LC_NUMERIC, ""); } else { @@ -492,13 +481,15 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng label_value = Glib::ustring(_("Non Uniform Scale")); } rstring->setContent(label_value.c_str()); - // this boring hack is to update the text with document scale inituialy loaded without root transform if (elemref) { - Geom::OptRect bounds = cast(elemref)->geometricBounds(); - if (bounds) { - anotation_width = bounds->width(); - rtext->setAttributeSvgDouble("x", pos[Geom::X] - (anotation_width / 2.0)); - rtspan->removeAttribute("style"); + auto text = cast(elemref); + if (text) { + text->rebuildLayout(); + if (Geom::OptRect bounds = text->geometricBounds()) { + anotation_width = bounds->width(); + rtext->setAttributeSvgDouble("x", pos[Geom::X] - (anotation_width / 2.0)); + rtspan->removeAttribute("style"); + } } } @@ -607,8 +598,12 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, Glib::ustring } std::stringstream stroke_w; setlocale (LC_NUMERIC, "C"); - - double stroke_width = Inkscape::Util::Quantity::convert(line_width, unit.get_abbreviation(), display_unit.c_str()); + double stroke_width; + if (legacy) { + stroke_width = Inkscape::Util::Quantity::convert(line_width, unit.get_abbreviation(), document->getDisplayUnit()->abbr.c_str()); + } else { + stroke_width = Inkscape::Util::Quantity::convert(line_width, "mm", "px") / getSPDoc()->getDocumentScale()[Geom::X]; + } stroke_w << stroke_width; setlocale (LC_NUMERIC, locale_base); style += "stroke-width:"; @@ -644,7 +639,7 @@ LPEMeasureSegments::doOnApply(SPLPEItem const* lpeitem) SPDocument *document = getSPDoc(); DocumentUndo::ScopedInsensitive _no_undo(document); Inkscape::XML::Node *styleNode = nullptr; - Inkscape::XML::Node* textNode = nullptr; + Inkscape::XML::Node *textNode = nullptr; Inkscape::XML::Node *root = document->getReprRoot(); for (unsigned i = 0; i < root->childCount(); ++i) { if (Glib::ustring(root->nthChild(i)->name()) == "svg:style") { @@ -683,6 +678,8 @@ LPEMeasureSegments::doOnApply(SPLPEItem const* lpeitem) textNode->setContent(styleContent.c_str()); } linked_items.update_satellites(); + lpeversion.param_setValue("1.3.1", true); + legacy = false; } bool @@ -830,6 +827,32 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) if (isOnClipboard()) { return; } + if (is_load) { + legacy = lpeversion.param_getSVGValue() < "1.3.1"; + auto msg = Glib::ustring(_("General\n" + "Display and position dimension lines and labels\n\n" + "Projection\n" + "Show a line with measurements based on the selected items\n\n" + "Options\n" + "Options for color, precision, label formatting and display\n\n" + "Tips\n" + "Custom styling: To further customize the styles, " + "use the XML editor to find out the class or ID, then use the " + "Style dialog to apply a new style.\n" + "Blacklists: allow to hide some segments or projection steps.\n" + "Multiple Measure LPEs: In the same object, in conjunction with blacklists," + "this allows for labels and measurements with different orientations or additional projections.\n" + "Set Defaults: For every LPE, default values can be set at the bottom.")); + + if (legacy) { + // helpdata is a message parameter, we must not need write this data into the SVG so we empty balue in this legacy files + helpdata.write_to_SVG(); // resert old legacy uneeded data + msg = Glib::ustring(_("IMPORTANT\n" + "This LPE is added with a old LPE\n" + "We keep your settings but advice you to remove and re-add to get better meassuring\n")) + msg; + } + helpdata.param_update_default(msg.c_str()); + } if (!linked_items.data().size()) { linked_items.read_from_SVG(); if (linked_items.data().size()) { @@ -904,7 +927,12 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } result.push_back(point[Geom::Y]); } - double dproj = Inkscape::Util::Quantity::convert(distance_projection, display_unit.c_str(), unit.get_abbreviation()); + double dproj; + if (legacy) { + dproj = Inkscape::Util::Quantity::convert(distance_projection, document->getDisplayUnit()->abbr.c_str(), unit.get_abbreviation()); + } else { + dproj = Inkscape::Util::Quantity::convert(distance_projection, "mm", "px") * getSPDoc()->getDocumentScale()[Geom::X]; + } Geom::Coord xpos = maxdistance + dproj; std::sort (result.begin(), result.end()); Geom::Path path; @@ -940,21 +968,30 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) //end projection prepare auto shape = cast(splpeitem); if (shape) { - //only check constrain viewbox on X - display_unit = document->getDisplayUnit()->abbr.c_str(); guint32 color32 = coloropacity.get_value(); bool colorchanged = false; if (color32 != rgb32) { colorchanged = true; } - rgb32 = color32; + rgb32 = std::move(color32); + bool unitchanged = false; + Glib::ustring currentunit = unit.get_abbreviation(); + if (currentunit != prevunit) { + unitchanged = true; + } + prevunit = std::move(currentunit); auto fontdesc_ustring = fontbutton.param_getSVGValue(); Pango::FontDescription fontdesc(fontdesc_ustring); double newfontsize = fontdesc.get_size() / (double)Pango::SCALE; - if (newfontsize != fontsize) { - fontsize = Inkscape::Util::Quantity::convert(newfontsize, "pt", display_unit.c_str()); + if (legacy) { + fontsize = Inkscape::Util::Quantity::convert(newfontsize, "pt", document->getDisplayUnit()->abbr.c_str()); + } else { + fontsize = Inkscape::Util::Quantity::convert(newfontsize, "pt", "px") / getSPDoc()->getDocumentScale()[Geom::X]; + } + if (newfontsize != prevfontsize) { fontsizechanged = true; } + prevfontsize = std::move(newfontsize); Geom::Point prev_stored = Geom::Point(0,0); Geom::Point start_stored = Geom::Point(0,0); Geom::Point end_stored = Geom::Point(0,0); @@ -1043,7 +1080,8 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) if (((Geom::are_near(prev, prev_stored, 0.01) && Geom::are_near(next, next_stored, 0.01)) || fix_overlaps_degree == 180) && Geom::are_near(start, start_stored, 0.01) && Geom::are_near(end, end_stored, 0.01) && - !this->refresh_widgets && !colorchanged && !fontsizechanged && !is_load && anotation_width) + !this->refresh_widgets && !colorchanged && !unitchanged && !fontsizechanged && + !is_load && !is_applied && anotation_width) { continue; } @@ -1089,10 +1127,11 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } } if (remove) { - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-"), counter, true, true, true); - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-start-"), counter, true, true, true); - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-end-"), counter, true, true, true); - createTextLabel(Geom::Point(), counter, 0, 0, true, true); + Geom::Point pos = Geom::Point(); + createLine(pos, pos, Glib::ustring("infoline-"), counter, true, true, true); + createLine(pos, pos, Glib::ustring("infoline-on-start-"), counter, true, true, true); + createLine(pos, pos, Glib::ustring("infoline-on-end-"), counter, true, true, true); + createTextLabel(pos, counter, 0, 0, true, true); continue; } Geom::Ray ray(hstart,hend); @@ -1169,7 +1208,11 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } else { createTextLabel(pos, counter, length, angle, remove, true); } - arrow_gap = 8 * Inkscape::Util::Quantity::convert(line_width, unit.get_abbreviation(), display_unit.c_str()); + if (legacy) { + arrow_gap = 8 * Inkscape::Util::Quantity::convert(line_width, unit.get_abbreviation(), document->getDisplayUnit()->abbr.c_str()); + } else { + arrow_gap = 8 * Inkscape::Util::Quantity::convert(line_width, "mm", "px") / getSPDoc()->getDocumentScale()[Geom::X]; + } if(flip_side) { arrow_gap *= -1; } @@ -1187,19 +1230,21 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) createLine(hstart, hend, Glib::ustring("infoline-"), counter, true, true, true); } } else { - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-"), counter, true, true, true); - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-start-"), counter, true, true, true); - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-end-"), counter, true, true, true); - createTextLabel(Geom::Point(), counter, 0, 0, true, true); + Geom::Point pos = Geom::Point(); + createLine(pos, pos, Glib::ustring("infoline-"), counter, true, true, true); + createLine(pos, pos, Glib::ustring("infoline-on-start-"), counter, true, true, true); + createLine(pos, pos, Glib::ustring("infoline-on-end-"), counter, true, true, true); + createTextLabel(pos, counter, 0, 0, true, true); } } } if (previous_size) { for (size_t counter = ncurves; counter < previous_size; counter++) { - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-"), counter, true, true, true); - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-start-"), counter, true, true, true); - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-end-"), counter, true, true, true); - createTextLabel(Geom::Point(), counter, 0, 0, true, true); + Geom::Point pos = Geom::Point(); + createLine(pos, pos, Glib::ustring("infoline-"), counter, true, true, true); + createLine(pos, pos, Glib::ustring("infoline-on-start-"), counter, true, true, true); + createLine(pos, pos, Glib::ustring("infoline-on-end-"), counter, true, true, true); + createTextLabel(pos, counter, 0, 0, true, true); } } previous_size = ncurves; diff --git a/src/live_effects/lpe-measure-segments.h b/src/live_effects/lpe-measure-segments.h index d50779a7685757083a71349e472e3deb240a5a38..b0d9ccc3984829cd278f5f18b6b761a49c526ca3 100644 --- a/src/live_effects/lpe-measure-segments.h +++ b/src/live_effects/lpe-measure-segments.h @@ -53,7 +53,7 @@ public: void processObjects(LPEAction lpe_action) override; Gtk::Widget * newWidget() override; void createLine(Geom::Point start,Geom::Point end, Glib::ustring name, size_t counter, bool main, bool remove, bool arrows = false); - void createTextLabel(Geom::Point pos, size_t counter, double length, Geom::Coord angle, bool remove, bool valid); + void createTextLabel(Geom::Point &pos, size_t counter, double length, Geom::Coord angle, bool remove, bool valid); void createArrowMarker(Glib::ustring mode); bool isWhitelist(size_t i, std::string listsegments, bool whitelist); void on_my_switch_page(Gtk::Widget* page, guint page_number); @@ -93,11 +93,13 @@ private: ScalarParam angle_projection; BoolParam avoid_overlapping; MessageParam helpdata; - Glib::ustring display_unit; + bool legacy = false; double fontsize; + double prevfontsize = 0; double anotation_width; double previous_size; guint32 rgb32; + Glib::ustring prevunit = ""; double arrow_gap; guint pagenumber; gchar const* locale_base; diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index aa90fa8111bd567ff2fe995c9be83780414b7c69..e6f3227c1892475ace61509bd944b67b40a63c70 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -43,6 +43,7 @@ LPEPowerClip::LPEPowerClip(LivePathEffectObject *lpeobject) registerParameter(&hide_clip); registerParameter(&message); message.param_set_min_height(55); + message.write_to_SVG(); // resert old legacy uneeded data _updating = false; _legacy = false; // legazy fix between 0.92.4 launch and 1.0beta1 diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 6378b5f1583f6db078bbbf20eb93ac6de9e7e474..c37307700cccea22410e7d7834926b974ff92803 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -180,7 +180,8 @@ LPEPowerStroke::LPEPowerStroke(LivePathEffectObject *lpeobject) : registerParameter(¬_jump); registerParameter(&sort_points); registerParameter(&message); - + + message.write_to_SVG(); // resert old legacy uneeded data interpolator_beta.addSlider(true); interpolator_beta.param_set_range(0.,1.); @@ -190,6 +191,7 @@ LPEPowerStroke::LPEPowerStroke(LivePathEffectObject *lpeobject) : scale_width.param_set_digits(1); recusion_limit = 0; has_recursion = false; + } LPEPowerStroke::~LPEPowerStroke() = default; @@ -261,6 +263,7 @@ void LPEPowerStroke::doOnRemove(SPLPEItem const* lpeitem) auto shape = cast(lpeitem_mutable); if (shape && !keep_paths) { + // medial width give half lpe_shape_revert_stroke_and_fill(shape, offset_points.median_width() * 2); } } diff --git a/src/live_effects/lpe-ruler.cpp b/src/live_effects/lpe-ruler.cpp index d88decb451f66461b0a547857498ff57c78735f0..e9519d8229e9114848e92e7cb64ff71afc157c9d 100644 --- a/src/live_effects/lpe-ruler.cpp +++ b/src/live_effects/lpe-ruler.cpp @@ -92,11 +92,19 @@ LPERuler::ruler_mark(Geom::Point const &A, Geom::Point const &n, MarkType const double real_mark_length = mark_length; SPDocument *document = getSPDoc(); if (document) { - real_mark_length = Inkscape::Util::Quantity::convert(real_mark_length, unit.get_abbreviation(), document->getDisplayUnit()->abbr.c_str()); + if (legacy) { + real_mark_length = Inkscape::Util::Quantity::convert(real_mark_length, unit.get_abbreviation(), document->getWidth().unit->abbr.c_str()); + } else { + real_mark_length = Inkscape::Util::Quantity::convert(real_mark_length, unit.get_abbreviation(), "px") / document->getDocumentScale()[Geom::X]; + } } double real_minor_mark_length = minor_mark_length; if (document) { - real_minor_mark_length = Inkscape::Util::Quantity::convert(real_minor_mark_length, unit.get_abbreviation(), document->getDisplayUnit()->abbr.c_str()); + if (legacy) { + real_minor_mark_length = Inkscape::Util::Quantity::convert(real_minor_mark_length, unit.get_abbreviation(), document->getWidth().unit->abbr.c_str()); + } else { + real_minor_mark_length = Inkscape::Util::Quantity::convert(real_minor_mark_length, unit.get_abbreviation(), "px") / document->getDocumentScale()[Geom::X]; + } } n_major = real_mark_length * n; n_minor = real_minor_mark_length * n; @@ -157,9 +165,19 @@ LPERuler::ruler_mark(Geom::Point const &A, Geom::Point const &n, MarkType const return seg; } +void +LPERuler::doOnApply(SPLPEItem const* lpeitem) +{ + lpeversion.param_setValue("1.3.1", true); + legacy = false; +} + Geom::Piecewise > LPERuler::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) { + if (is_load) { + legacy = lpeversion.param_getSVGValue() < "1.3.1"; + } using namespace Geom; const int mminterval = static_cast(major_mark_steps); @@ -174,15 +192,32 @@ LPERuler::doEffect_pwd2 (Geom::Piecewise > const & pwd2_i //find at which times to draw a mark: std::vector s_cuts; SPDocument *document = getSPDoc(); + if (document) { - auto const prev_display_unit = std::move(display_unit); - display_unit = getSPDoc()->getDisplayUnit()->abbr; - if (!display_unit.empty() && display_unit != prev_display_unit) { - //_document->getDocumentScale().inverse() - mark_distance.param_set_value(Inkscape::Util::Quantity::convert(mark_distance, display_unit.c_str(), prev_display_unit.c_str())); - offset.param_set_value(Inkscape::Util::Quantity::convert(offset, display_unit.c_str(), prev_display_unit.c_str())); - minor_mark_length.param_set_value(Inkscape::Util::Quantity::convert(minor_mark_length, display_unit.c_str(), prev_display_unit.c_str())); - mark_length.param_set_value(Inkscape::Util::Quantity::convert(mark_length, display_unit.c_str(), prev_display_unit.c_str())); + bool write = false; + if (legacy) { + auto const punit = prev_unit; + prev_unit = getSPDoc()->getDisplayUnit()->abbr; + if (!punit.empty() && prev_unit != punit) { + //_document->getDocumentScale().inverse() + mark_distance.param_set_value(Inkscape::Util::Quantity::convert(mark_distance, prev_unit.c_str(), punit.c_str())); + offset.param_set_value(Inkscape::Util::Quantity::convert(offset, prev_unit.c_str(), punit.c_str())); + minor_mark_length.param_set_value(Inkscape::Util::Quantity::convert(minor_mark_length, prev_unit.c_str(), punit.c_str())); + mark_length.param_set_value(Inkscape::Util::Quantity::convert(mark_length, prev_unit.c_str(), punit.c_str())); + write = true; + } + } else { + auto const punit = prev_unit; + prev_unit = unit.get_abbreviation(); + if (!punit.empty() && prev_unit != punit) { + mark_distance.param_set_value(Inkscape::Util::Quantity::convert(mark_distance, punit, unit.get_abbreviation())); + offset.param_set_value(Inkscape::Util::Quantity::convert(offset, punit, unit.get_abbreviation())); + minor_mark_length.param_set_value(Inkscape::Util::Quantity::convert(minor_mark_length, punit, unit.get_abbreviation())); + mark_length.param_set_value(Inkscape::Util::Quantity::convert(mark_length, punit, unit.get_abbreviation())); + write = true; + } + } + if (write) { minor_mark_length.write_to_SVG(); mark_length.write_to_SVG(); mark_distance.write_to_SVG(); @@ -191,11 +226,19 @@ LPERuler::doEffect_pwd2 (Geom::Piecewise > const & pwd2_i } double real_mark_distance = mark_distance; if (document) { - real_mark_distance = Inkscape::Util::Quantity::convert(real_mark_distance, unit.get_abbreviation(), document->getDisplayUnit()->abbr.c_str()); + if (legacy) { + real_mark_distance = Inkscape::Util::Quantity::convert(real_mark_distance, unit.get_abbreviation(), document->getWidth().unit->abbr.c_str()); + } else { + real_mark_distance = Inkscape::Util::Quantity::convert(real_mark_distance, unit.get_abbreviation(), "px") / document->getDocumentScale()[Geom::X]; + } } double real_offset = offset; if (document) { - real_offset = Inkscape::Util::Quantity::convert(real_offset, unit.get_abbreviation(), document->getDisplayUnit()->abbr.c_str()); + if (legacy) { + real_offset = Inkscape::Util::Quantity::convert(real_offset, unit.get_abbreviation(), document->getWidth().unit->abbr.c_str()); + } else { + real_offset = Inkscape::Util::Quantity::convert(real_offset, unit.get_abbreviation(), "px") / document->getDocumentScale()[Geom::X]; + } } for (double s = real_offset; s > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) override; private: @@ -63,7 +63,8 @@ private: EnumParam mark_dir; ScalarParam offset; EnumParam border_marks; - Glib::ustring display_unit; + Glib::ustring prev_unit; + bool legacy = false; static Geom::Point n_major, n_minor; // used for internal computations LPERuler(const LPERuler&) = delete; diff --git a/src/live_effects/lpe-tiling.cpp b/src/live_effects/lpe-tiling.cpp index 1e5f14cee541e0ae9d652d7bc9bac6c00d4301aa..0abd9f10adae3b12b86e2b440cee927fed1bfb0a 100644 --- a/src/live_effects/lpe-tiling.cpp +++ b/src/live_effects/lpe-tiling.cpp @@ -175,7 +175,7 @@ LPETiling::LPETiling(LivePathEffectObject *lpeobject) : prev_num_rows = num_rows; _knotholder = nullptr; reset = link_styles; - display_unit = getSPDoc()->getDisplayUnit()->abbr; + display_unit = getSPDoc()->getWidth().unit->abbr; } LPETiling::~LPETiling() @@ -1178,12 +1178,17 @@ LPETiling::doOnApply(SPLPEItem const* lpeitem) } else { transformorigin.param_setValue("", true); } + lpeversion.param_setValue("1.3.1", true); + legacy = false; doBeforeEffect(lpeitem); } void LPETiling::doBeforeEffect (SPLPEItem const* lpeitem) { + if (is_load) { + legacy = lpeversion.param_getSVGValue() < "1.3.1"; + } auto transformorigin_str = lpeitem->getAttribute("transform"); if (transformorigin_str) { transformorigin.read_from_SVG(); @@ -1238,17 +1243,22 @@ LPETiling::doBeforeEffect (SPLPEItem const* lpeitem) lpesatellites.update_satellites(); } } - auto const prev_display_unit = std::move(display_unit); - display_unit = getSPDoc()->getDisplayUnit()->abbr; - if (!display_unit.empty() && display_unit != prev_display_unit) { - //_document->getDocumentScale().inverse() - gapx.param_set_value(Inkscape::Util::Quantity::convert(gapx, display_unit.c_str(), prev_display_unit.c_str())); - gapy.param_set_value(Inkscape::Util::Quantity::convert(gapy, display_unit.c_str(), prev_display_unit.c_str())); - gapx.write_to_SVG(); - gapy.write_to_SVG(); + if (legacy) { + auto const prev_display_unit = std::move(display_unit); + display_unit = getSPDoc()->getDisplayUnit()->abbr; + if (!display_unit.empty() && display_unit != prev_display_unit) { + //_document->getDocumentScale().inverse() + gapx.param_set_value(Inkscape::Util::Quantity::convert(gapx, display_unit.c_str(), prev_display_unit.c_str())); + gapy.param_set_value(Inkscape::Util::Quantity::convert(gapy, display_unit.c_str(), prev_display_unit.c_str())); + gapx.write_to_SVG(); + gapy.write_to_SVG(); + } + gapx_unit = Inkscape::Util::Quantity::convert(gapx, unit.get_abbreviation(), display_unit.c_str()); + gapy_unit = Inkscape::Util::Quantity::convert(gapy, unit.get_abbreviation(), display_unit.c_str()); + } else { + gapx_unit = Inkscape::Util::Quantity::convert(gapx, unit.get_abbreviation(), "px") / getSPDoc()->getDocumentScale()[Geom::X]; + gapy_unit = Inkscape::Util::Quantity::convert(gapy, unit.get_abbreviation(), "px") / getSPDoc()->getDocumentScale()[Geom::X]; } - gapx_unit = Inkscape::Util::Quantity::convert(gapx, unit.get_abbreviation(), display_unit.c_str()); - gapy_unit = Inkscape::Util::Quantity::convert(gapy, unit.get_abbreviation(), display_unit.c_str()); original_bbox(sp_lpe_item, false, true, transformoriginal); originalbbox = Geom::OptRect(boundingbox_X,boundingbox_Y); Geom::Point A = Point(boundingbox_X.min() - (gapx_unit / 2.0), boundingbox_Y.min() - (gapy_unit / 2.0)); @@ -1672,8 +1682,12 @@ void KnotHolderEntityCopyGapX::knot_set(Geom::Point const &p, Geom::Point const& Geom::Point point = (*lpe->originalbbox).corner(1); point *= lpe->transformoriginal.inverse(); double value = s[Geom::X] - point[Geom::X]; - Glib::ustring display_unit = SP_ACTIVE_DOCUMENT->getDisplayUnit()->abbr.c_str(); - value = Inkscape::Util::Quantity::convert((value/lpe->end_scale(lpe->scaleok, false)) * 2, display_unit.c_str(),lpe->unit.get_abbreviation()); + if (lpe->legacy) { + Glib::ustring doc_unit = SP_ACTIVE_DOCUMENT->getWidth().unit->abbr.c_str(); + value = Inkscape::Util::Quantity::convert((value/lpe->end_scale(lpe->scaleok, false)) * 2, doc_unit.c_str(),lpe->unit.get_abbreviation()); + } else { + value = Inkscape::Util::Quantity::convert((value/lpe->end_scale(lpe->scaleok, false)) * 2, "px", lpe->unit.get_abbreviation()) * SP_ACTIVE_DOCUMENT->getDocumentScale()[Geom::X]; + } lpe->gapx.param_set_value(value); lpe->gapx.write_to_SVG(); } @@ -1688,8 +1702,12 @@ void KnotHolderEntityCopyGapY::knot_set(Geom::Point const &p, Geom::Point const& Geom::Point point = (*lpe->originalbbox).corner(3); point *= lpe->transformoriginal.inverse(); double value = s[Geom::Y] - point[Geom::Y]; - Glib::ustring display_unit = SP_ACTIVE_DOCUMENT->getDisplayUnit()->abbr.c_str(); - value = Inkscape::Util::Quantity::convert((value/lpe->end_scale(lpe->scaleok, false)) * 2, display_unit.c_str(),lpe->unit.get_abbreviation()); + if (lpe->legacy) { + Glib::ustring doc_unit = SP_ACTIVE_DOCUMENT->getWidth().unit->abbr.c_str(); + value = Inkscape::Util::Quantity::convert((value/lpe->end_scale(lpe->scaleok, false)) * 2, doc_unit.c_str(),lpe->unit.get_abbreviation()); + } else { + value = Inkscape::Util::Quantity::convert((value/lpe->end_scale(lpe->scaleok, false)) * 2, "px", lpe->unit.get_abbreviation()) * SP_ACTIVE_DOCUMENT->getDocumentScale()[Geom::X]; + } lpe->gapy.param_set_value(value); lpe->gapy.write_to_SVG(); } @@ -1701,8 +1719,13 @@ Geom::Point KnotHolderEntityCopyGapX::knot_get() const Geom::Point ret = Geom::Point(Geom::infinity(),Geom::infinity()); if (lpe->originalbbox) { auto bbox = (*lpe->originalbbox); - Glib::ustring display_unit = SP_ACTIVE_DOCUMENT->getDisplayUnit()->abbr.c_str(); - double value = Inkscape::Util::Quantity::convert(lpe->gapx, lpe->unit.get_abbreviation(), display_unit.c_str()); + double value; + if (lpe->legacy) { + Glib::ustring prev_unit = SP_ACTIVE_DOCUMENT->getDisplayUnit()->abbr.c_str(); + value = Inkscape::Util::Quantity::convert(lpe->gapx, lpe->unit.get_abbreviation(), prev_unit.c_str()); + } else { + value = Inkscape::Util::Quantity::convert(lpe->gapx, lpe->unit.get_abbreviation(), "px") / SP_ACTIVE_DOCUMENT->getDocumentScale()[Geom::X]; + } double scale = lpe->scaleok; ret = (bbox).corner(1) + Geom::Point((value * lpe->end_scale(scale, false))/2.0,0); ret *= lpe->transformoriginal.inverse(); @@ -1716,8 +1739,13 @@ Geom::Point KnotHolderEntityCopyGapY::knot_get() const Geom::Point ret = Geom::Point(Geom::infinity(),Geom::infinity()); if (lpe->originalbbox) { auto bbox = (*lpe->originalbbox); - Glib::ustring display_unit = SP_ACTIVE_DOCUMENT->getDisplayUnit()->abbr.c_str(); - double value = Inkscape::Util::Quantity::convert(lpe->gapy, lpe->unit.get_abbreviation(), display_unit.c_str()); + double value; + if (lpe->legacy) { + Glib::ustring prev_unit = SP_ACTIVE_DOCUMENT->getDisplayUnit()->abbr.c_str(); + value = Inkscape::Util::Quantity::convert(lpe->gapy, lpe->unit.get_abbreviation(), prev_unit.c_str()); + } else { + value = Inkscape::Util::Quantity::convert(lpe->gapy, lpe->unit.get_abbreviation(), "px") / SP_ACTIVE_DOCUMENT->getDocumentScale()[Geom::X]; + } double scale = lpe->scaleok; ret = (bbox).corner(3) + Geom::Point(0,(value * lpe->end_scale(scale, false))/2.0); ret *= lpe->transformoriginal.inverse(); diff --git a/src/live_effects/lpe-tiling.h b/src/live_effects/lpe-tiling.h index d482fa435cd7515b6f066eb81cffa6518ffe1119..c202cb89f0bc585c1b3e986263c0e0f604152ecb 100644 --- a/src/live_effects/lpe-tiling.h +++ b/src/live_effects/lpe-tiling.h @@ -129,6 +129,7 @@ private: gdouble scaleok = 1.0; Glib::ustring display_unit; Glib::ustring prev_unit = "px"; + bool legacy = false; std::vector random_x; std::vector random_y; std::vector random_s; diff --git a/src/live_effects/parameter/message.cpp b/src/live_effects/parameter/message.cpp index 963a7cbd71d1a500820d053d70561d448f7edb94..0fb6549ca20864e1ba2467ffcd99bc16f59f9d5d 100644 --- a/src/live_effects/parameter/message.cpp +++ b/src/live_effects/parameter/message.cpp @@ -23,7 +23,6 @@ MessageParam::MessageParam( const Glib::ustring& label, const Glib::ustring& tip Effect* effect, const gchar * default_message, Glib::ustring legend, Gtk::Align halign, Gtk::Align valign, double marginstart, double marginend) : Parameter(label, tip, key, wr, effect), - message(default_message), defmessage(default_message), _legend(std::move(legend)), _halign(halign), @@ -41,7 +40,7 @@ MessageParam::MessageParam( const Glib::ustring& label, const Glib::ustring& tip void MessageParam::param_set_default() { - param_setValue(defmessage); + // do nothing } void @@ -60,7 +59,9 @@ MessageParam::param_readSVGValue(const gchar * strvalue) Glib::ustring MessageParam::param_getSVGValue() const { - return message; + return ""; // we dorn want to store messages in the SVG we store in LPE volatile + // variables and get content with + // param_getDefaultSVGValue() instead } Glib::ustring @@ -87,7 +88,7 @@ MessageParam::param_newWidget() widg_frame->set_margin_end(_marginend); widg_frame->set_margin_start(_marginstart); - _label = Gtk::make_managed(message, Gtk::ALIGN_END); + _label = Gtk::make_managed(defmessage, Gtk::ALIGN_END); _label->set_use_underline (true); _label->set_use_markup(); _label->set_line_wrap(true); @@ -104,10 +105,10 @@ MessageParam::param_newWidget() void MessageParam::param_setValue(const gchar * strvalue) { - if (strcmp(strvalue, message) != 0) { + if (g_strcmp0(strvalue, defmessage.c_str())) { param_effect->refresh_widgets = true; } - message = strvalue; + defmessage = strvalue; } diff --git a/src/live_effects/parameter/message.h b/src/live_effects/parameter/message.h index aa6a8da758c7480fd1c1823f23d1578851bac4a2..2409790019e58fc428bff528dcc6d835bf2b53f3 100644 --- a/src/live_effects/parameter/message.h +++ b/src/live_effects/parameter/message.h @@ -40,15 +40,14 @@ public: void param_set_default() override; void param_set_min_height(int height); - const gchar * get_value() const { return message; }; + const gchar * get_value() const { return defmessage.c_str(); }; ParamType paramType() const override { return ParamType::MESSAGE; }; private: Gtk::Label * _label; int _min_height; MessageParam(const MessageParam&) = delete; MessageParam& operator=(const MessageParam&) = delete; - const gchar * message; - const gchar * defmessage; + Glib::ustring defmessage; Glib::ustring _legend; Gtk::Align _halign; Gtk::Align _valign; diff --git a/src/live_effects/parameter/unit.cpp b/src/live_effects/parameter/unit.cpp index cdd753407b053444cd8afddb996ebae96150391a..10a2e57849dded8ee992d15eb4be57a29d895344 100644 --- a/src/live_effects/parameter/unit.cpp +++ b/src/live_effects/parameter/unit.cpp @@ -22,21 +22,25 @@ UnitParam::UnitParam(const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, Glib::ustring default_unit) : Parameter(label, tip, key, wr, effect) - , defunit{unit_table.getUnit(default_unit)} - , unit{defunit} + , defunit{default_unit} { + unit = std::make_unique(*unit_table.getUnit(default_unit)); } UnitParam::~UnitParam() { - free_unit(); + if (unit) { + delete unit.get(); + unit.release(); + } } + bool UnitParam::param_readSVGValue(const gchar * strvalue) { if (strvalue) { - param_set_value(*unit_table.getUnit(strvalue)); + param_set_value(strvalue); return true; } return false; @@ -45,39 +49,47 @@ UnitParam::param_readSVGValue(const gchar * strvalue) Glib::ustring UnitParam::param_getSVGValue() const { - return unit->abbr; + return unit.get()->abbr; } Glib::ustring UnitParam::param_getDefaultSVGValue() const { - return defunit->abbr; + return defunit; } void UnitParam::param_set_default() { - param_set_value(*defunit); + param_set_value(defunit.c_str()); } void UnitParam::param_update_default(const gchar * default_unit) { - defunit = unit_table.getUnit((Glib::ustring)default_unit); + defunit = "px"; // fallback to px + if (default_unit) { + defunit = default_unit; + } } void -UnitParam::param_set_value(Inkscape::Util::Unit const &val) +UnitParam::param_set_value(const gchar * strvalue) { - param_effect->refresh_widgets = true; - free_unit(); - unit = new Inkscape::Util::Unit(val); + if (strvalue) { + param_effect->refresh_widgets = true; + if (unit) { + delete unit.get(); + unit.release(); + } + unit = std::make_unique(*unit_table.getUnit(strvalue)); + } } const gchar * UnitParam::get_abbreviation() const { - return unit->abbr.c_str(); + return unit.get()->abbr.c_str(); } Gtk::Widget * @@ -89,19 +101,11 @@ UnitParam::param_newWidget() param_effect->getRepr(), param_effect->getSPDoc() ); - unit_menu->setUnit(unit->abbr); + unit_menu->setUnit(unit.get()->abbr); unit_menu->set_undo_parameters(_("Change unit parameter"), INKSCAPE_ICON("dialog-path-effects")); return unit_menu; } -void -UnitParam::free_unit() -{ - // Exception: If we just refer to unit_table.getUnit(default_unit), leave it - if (unit && unit != defunit) { - delete unit; - } -} } // Inkscape::LivePathEffect diff --git a/src/live_effects/parameter/unit.h b/src/live_effects/parameter/unit.h index 21ff48b705dcd192a6c4a7a18e3bf56b1205aa4b..1c4bd59ccb9b4e9267559ace07f7532268dac50d 100644 --- a/src/live_effects/parameter/unit.h +++ b/src/live_effects/parameter/unit.h @@ -37,19 +37,16 @@ public: Glib::ustring param_getSVGValue() const override; Glib::ustring param_getDefaultSVGValue() const override; void param_set_default() override; - void param_set_value(Inkscape::Util::Unit const &val); + void param_set_value(const gchar * unit); void param_update_default(const gchar * default_unit) override; const gchar *get_abbreviation() const; Gtk::Widget * param_newWidget() override; - operator Inkscape::Util::Unit const *() const { return unit; } ParamType paramType() const override { return ParamType::UNIT; }; private: - Inkscape::Util::Unit const *defunit; - Inkscape::Util::Unit const *unit; - - void free_unit(); + Glib::ustring defunit; + std::unique_ptr unit; }; } // namespace LivePathEffect