diff options
| author | Liam P. White <inkscapebrony@gmail.com> | 2014-11-26 01:10:30 +0000 |
|---|---|---|
| committer | Liam P. White <inkscapebrony@gmail.com> | 2014-11-26 01:10:30 +0000 |
| commit | 6c87088ed548a3da4388ea95bba82aea798c901a (patch) | |
| tree | e4269aab0a32957163935ec6b828b25d00613d68 /src | |
| parent | Update to trunk r13750 (diff) | |
| parent | Add CMake file to find LCMS2 (diff) | |
| download | inkscape-6c87088ed548a3da4388ea95bba82aea798c901a.tar.gz inkscape-6c87088ed548a3da4388ea95bba82aea798c901a.zip | |
Update to trunk r13766
(bzr r13341.5.24)
Diffstat (limited to 'src')
49 files changed, 224 insertions, 166 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9ab3c28a9..680d3bae5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -517,10 +517,19 @@ set(inkscape_SRC # make executable for INKSCAPE add_executable(inkscape ${main_SRC} ${inkscape_SRC} ${sp_SRC}) +if(UNIX) +# message after building. +add_custom_command( + TARGET inkscape + POST_BUILD MAIN_DEPENDENCY inkscape + COMMAND ${CMAKE_COMMAND} -E echo 'now run: \"make install\" to copy runtime files & scripts to ${CMAKE_INSTALL_PREFIX}' +) +endif() + add_dependencies(inkscape inkscape_version) target_link_libraries(inkscape - # order from automake + # order from automake #sp_LIB nrtype_LIB diff --git a/src/document.cpp b/src/document.cpp index 2832536af..2625ef8fc 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -602,6 +602,14 @@ Inkscape::Util::Unit const* SPDocument::getDefaultUnit() const return nv ? nv->getDefaultUnit() : unit_table.getUnit("pt"); } +/// guaranteed not to return nullptr +// returns 'px' units as default, like legacy Inkscape +Inkscape::Util::Unit const& SPDocument::getSVGUnit() const +{ + SPNamedView const* nv = sp_document_namedview(this, NULL); + return nv ? nv->getSVGUnit() : *unit_table.getUnit("px"); +} + Inkscape::Util::Quantity SPDocument::getWidth() const { g_return_val_if_fail(this->priv != NULL, Inkscape::Util::Quantity(0.0, unit_table.getUnit(""))); @@ -625,16 +633,10 @@ void SPDocument::setWidth(const Inkscape::Util::Quantity &width) if (root->width.unit) old_units = unit_table.getUnit(root->width.unit); gdouble old_converted = Inkscape::Util::Quantity::convert(root->width.value, old_units, width.unit); + root->width.computed = width.value("px"); - /* SVG does not support meters as a unit, so we must translate meters to - * cm when writing */ - if (*width.unit == *unit_table.getUnit("m")) { - root->width.value = width.value("cm"); - root->width.unit = SVGLength::CM; - } else { - root->width.value = width.quantity; - root->width.unit = (SVGLength::Unit) width.unit->svgUnit(); - } + root->width.value = width.quantity; + root->width.unit = (SVGLength::Unit) width.unit->svgUnit(); if (root->viewBox_set) root->viewBox.setMax(Geom::Point(root->viewBox.left() + (root->width.value / old_converted) * root->viewBox.width(), root->viewBox.bottom())); @@ -666,16 +668,10 @@ void SPDocument::setHeight(const Inkscape::Util::Quantity &height) if (root->height.unit) old_units = unit_table.getUnit(root->height.unit); gdouble old_converted = Inkscape::Util::Quantity::convert(root->height.value, old_units, height.unit); + root->height.computed = height.value("px"); - /* SVG does not support meters as a unit, so we must translate meters to - * cm when writing */ - if (*height.unit == *unit_table.getUnit("m")) { - root->height.value = height.value("cm"); - root->height.unit = SVGLength::CM; - } else { - root->height.value = height.quantity; - root->height.unit = (SVGLength::Unit) height.unit->svgUnit(); - } + root->height.value = height.quantity; + root->height.unit = (SVGLength::Unit) height.unit->svgUnit(); if (root->viewBox_set) root->viewBox.setMax(Geom::Point(root->viewBox.right(), root->viewBox.top() + (root->height.value / old_converted) * root->viewBox.height())); diff --git a/src/document.h b/src/document.h index 2f865367e..a8b79eb9e 100644 --- a/src/document.h +++ b/src/document.h @@ -241,6 +241,7 @@ public: SPDocument *doRef(); SPDocument *doUnref(); Inkscape::Util::Unit const* getDefaultUnit() const; + Inkscape::Util::Unit const& getSVGUnit() const; Inkscape::Util::Quantity getWidth() const; Inkscape::Util::Quantity getHeight() const; Geom::Point getDimensions() const; diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 5a9a28ef9..1f48d2097 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -206,7 +206,7 @@ static void sp_shape_render(SPShape *shape, CairoRenderContext *ctx) } else if (marker->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { tr = Geom::Rotate::from_degrees( 180.0 ) * sp_shape_marker_get_transform_at_start(pathv.begin()->front()); } else { - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(pathv.begin()->front().pointAt(0)); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(pathv.begin()->front().pointAt(0)); } sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); } @@ -224,7 +224,7 @@ static void sp_shape_render(SPShape *shape, CairoRenderContext *ctx) if (marker->orient_mode != MARKER_ORIENT_ANGLE) { tr = sp_shape_marker_get_transform_at_start(path_it->front()); } else { - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(path_it->front().pointAt(0)); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(path_it->front().pointAt(0)); } sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); } @@ -241,7 +241,7 @@ static void sp_shape_render(SPShape *shape, CairoRenderContext *ctx) if (marker->orient_mode != MARKER_ORIENT_ANGLE) { tr = sp_shape_marker_get_transform(*curve_it1, *curve_it2); } else { - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(curve_it1->pointAt(1)); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(curve_it1->pointAt(1)); } sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); @@ -257,7 +257,7 @@ static void sp_shape_render(SPShape *shape, CairoRenderContext *ctx) if (marker->orient_mode != MARKER_ORIENT_ANGLE) { tr = sp_shape_marker_get_transform_at_end(lastcurve); } else { - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(lastcurve.pointAt(1)); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(lastcurve.pointAt(1)); } sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); } @@ -281,7 +281,7 @@ static void sp_shape_render(SPShape *shape, CairoRenderContext *ctx) if (marker->orient_mode != MARKER_ORIENT_ANGLE) { tr = sp_shape_marker_get_transform_at_end(lastcurve); } else { - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(lastcurve.pointAt(1)); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(lastcurve.pointAt(1)); } sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp index 0f43fbca1..f7b6626c4 100644 --- a/src/extension/internal/emf-print.cpp +++ b/src/extension/internal/emf-print.cpp @@ -144,7 +144,7 @@ unsigned int PrintEmf::begin(Inkscape::Extension::Print *mod, SPDocument *doc) // width and height in px _width = doc->getWidth().value("px"); _height = doc->getHeight().value("px"); - _doc_unit_scale = Inkscape::Util::Quantity::convert(1, (doc->getDefaultUnit()), "px"); + _doc_unit_scale = Inkscape::Util::Quantity::convert(1, &doc->getSVGUnit(), "px"); // initialize a few global variables hbrush = hbrushOld = hpen = 0; diff --git a/src/extension/internal/grid.cpp b/src/extension/internal/grid.cpp index 0059bbec2..f4e0e5843 100644 --- a/src/extension/internal/grid.cpp +++ b/src/extension/internal/grid.cpp @@ -113,7 +113,7 @@ Grid::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *doc bounding_area = temprec; } - gdouble scale = Inkscape::Util::Quantity::convert(1, "px", (document->doc())->getDefaultUnit()); + gdouble scale = Inkscape::Util::Quantity::convert(1, "px", &document->doc()->getSVGUnit()); bounding_area *= Geom::Scale(scale); Geom::Point spacings( scale * module->get_param_float("xspacing"), scale * module->get_param_float("yspacing") ); diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 07d9e63e8..8cef9a3a3 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -160,11 +160,11 @@ double LPERoughen::sign(double randNumber) Geom::Point LPERoughen::randomize() { - Inkscape::Util::Unit const *doc_units = SP_ACTIVE_DESKTOP->namedview->doc_units; + Inkscape::Util::Unit const *svg_units = SP_ACTIVE_DESKTOP->namedview->svg_units; double displaceXParsed = Inkscape::Util::Quantity::convert( - displaceX * globalRandomize, unit.get_abbreviation(), doc_units->abbr); + displaceX * globalRandomize, unit.get_abbreviation(), svg_units->abbr); double displaceYParsed = Inkscape::Util::Quantity::convert( - displaceY * globalRandomize, unit.get_abbreviation(), doc_units->abbr); + displaceY * globalRandomize, unit.get_abbreviation(), svg_units->abbr); Geom::Point output = Geom::Point(sign(displaceXParsed), sign(displaceYParsed)); return output; @@ -175,7 +175,7 @@ void LPERoughen::doEffect(SPCurve *curve) Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(curve->get_pathvector()); curve->reset(); - Inkscape::Util::Unit const *doc_units = SP_ACTIVE_DESKTOP->namedview->doc_units; + Inkscape::Util::Unit const *svg_units = SP_ACTIVE_DESKTOP->namedview->svg_units; for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { if (path_it->empty()) @@ -221,7 +221,7 @@ void LPERoughen::doEffect(SPCurve *curve) nCurve->lineto(A3); } double length = Inkscape::Util::Quantity::convert( - curve_it1->length(0.001), doc_units->abbr, unit.get_abbreviation()); + curve_it1->length(0.001), svg_units->abbr, unit.get_abbreviation()); std::size_t splits = 0; if (method == DM_SEGMENTS) { splits = segments; diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 406ea6da2..d9c61544b 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -521,11 +521,9 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone) if (!strcmp(orig->getId(), old_ids[j])) { // we have both orig and clone in selection, relink // std::cout << id << " old, its ori: " << orig->getId() << "; will relink:" << new_ids[i] << " to " << new_ids[j] << "\n"; - gchar *newref = g_strdup_printf("#%s", new_ids[j]); SPObject *new_clone = doc->getObjectById(new_ids[i]); - new_clone->getRepr()->setAttribute("xlink:href", newref); + new_clone->getRepr()->setAttribute("xlink:href", '#' + new_ids[j]); new_clone->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - g_free(newref); } } } else { @@ -534,9 +532,7 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone) for (guint j = 0; j < old_ids.size(); j++) { gchar *source_href = offset->sourceHref; if (source_href && source_href[0]=='#' && !strcmp(source_href+1, old_ids[j])) { - gchar *newref = g_strdup_printf("#%s", new_ids[j]); - doc->getObjectById(new_ids[i])->getRepr()->setAttribute("xlink:href", newref); - g_free(newref); + doc->getObjectById(new_ids[i])->getRepr()->setAttribute("xlink:href", '#' + new_ids[j]); } } } @@ -2884,10 +2880,12 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) if (desktop == NULL) { return; } - + + Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::SVGOStringStream os; SPObject * firstItem = NULL; - for (const GSList * item = desktop->selection->itemList(); item != NULL; item = item->next) { + for (const GSList * item = selection->itemList(); item != NULL; item = item->next) { if (SP_IS_SHAPE(item->data) || SP_IS_TEXT(item->data)) { if (firstItem) { os << "|"; @@ -2905,10 +2903,10 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) Inkscape::XML::Node *lpe_repr = xml_doc->createElement("inkscape:path-effect"); { lpe_repr->setAttribute("effect", "fill_between_many"); - lpe_repr->setAttribute("linkedpaths", os.str().c_str()); + lpe_repr->setAttribute("linkedpaths", os.str()); desktop->doc()->getDefs()->getRepr()->addChild(lpe_repr, NULL); // adds to <defs> and assigns the 'id' attribute } - const gchar * lpe_id = lpe_repr->attribute("id"); + std::string lpe_id_href = '#' + lpe_repr->attribute("id"); Inkscape::GC::release(lpe_repr); // create the new path @@ -2920,13 +2918,15 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) SPObject *clone_obj = desktop->doc()->getObjectById(clone->attribute("id")); SPLPEItem *clone_lpeitem = dynamic_cast<SPLPEItem *>(clone_obj); if (clone_lpeitem) { - gchar *href = g_strdup_printf("#%s", lpe_id); - clone_lpeitem->addPathEffect(href, false); - g_free(href); + clone_lpeitem->addPathEffect(lpe_id_href, false); } } DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_CLONE_ORIGINAL_PATH_LPE, _("Fill between many")); + // select the new object: + selection->set(clone); + + Inkscape::GC::release(clone); } else { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select path(s) to fill.")); } @@ -3174,7 +3174,7 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) the_group->setAttribute("style", NULL); std::string id = symbol_repr->attribute("id"); id += "_transform"; - the_group->setAttribute("id", id.c_str()); + the_group->setAttribute("id", id); } @@ -3192,10 +3192,7 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) // Create <use> pointing to new symbol (to replace the moved objects). Inkscape::XML::Node *clone = xml_doc->createElement("svg:use"); - const gchar *symbol_id = symbol_repr->attribute("id"); - gchar *href_str = g_strdup_printf("#%s", symbol_id); - clone->setAttribute("xlink:href", href_str, false); - g_free(href_str); + clone->setAttribute("xlink:href", '#'+symbol_repr->attribute("id"), false); the_parent_repr->appendChild(clone); @@ -3286,7 +3283,7 @@ void sp_selection_unsymbol(SPDesktop *desktop) // Need to delete <symbol>; all <use> elements that referenced <symbol> should // auto-magically reference <g> (if <symbol> deleted after setting <g> 'id'). Glib::ustring id = symbol->getAttribute("id"); - group->setAttribute("id",id.c_str()); + group->setAttribute("id", id); symbol->deleteObject(true); // Change selection to new <g> element. @@ -4084,9 +4081,7 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ Inkscape::GC::release(group); } - gchar *value_str = g_strdup_printf("url(#%s)", mask_id); - apply_mask_to->setAttribute(attributeName, value_str); - g_free(value_str); + apply_mask_to->setAttribute(attributeName, Glib::ustring("url(#") + mask_id + ')'); } diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 96c7fb49b..a9ae9e465 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -1306,8 +1306,8 @@ gboolean Inkscape::SelTrans::centerRequest(Geom::Point &pt, guint state) // status text Inkscape::Util::Quantity x_q = Inkscape::Util::Quantity(pt[Geom::X], "px"); Inkscape::Util::Quantity y_q = Inkscape::Util::Quantity(pt[Geom::Y], "px"); - GString *xs = g_string_new(x_q.string(_desktop->namedview->doc_units).c_str()); - GString *ys = g_string_new(y_q.string(_desktop->namedview->doc_units).c_str()); + GString *xs = g_string_new(x_q.string(_desktop->namedview->display_units).c_str()); + GString *ys = g_string_new(y_q.string(_desktop->namedview->display_units).c_str()); _message_context.setF(Inkscape::NORMAL_MESSAGE, _("Move <b>center</b> to %s, %s"), xs->str, ys->str); g_string_free(xs, FALSE); g_string_free(ys, FALSE); @@ -1460,8 +1460,8 @@ void Inkscape::SelTrans::moveTo(Geom::Point const &xy, guint state) // status text Inkscape::Util::Quantity x_q = Inkscape::Util::Quantity(dxy[Geom::X], "px"); Inkscape::Util::Quantity y_q = Inkscape::Util::Quantity(dxy[Geom::Y], "px"); - GString *xs = g_string_new(x_q.string(_desktop->namedview->doc_units).c_str()); - GString *ys = g_string_new(y_q.string(_desktop->namedview->doc_units).c_str()); + GString *xs = g_string_new(x_q.string(_desktop->namedview->display_units).c_str()); + GString *ys = g_string_new(y_q.string(_desktop->namedview->display_units).c_str()); _message_context.setF(Inkscape::NORMAL_MESSAGE, _("<b>Move</b> by %s, %s; with <b>Ctrl</b> to restrict to horizontal/vertical; with <b>Shift</b> to disable snapping"), xs->str, ys->str); g_string_free(xs, TRUE); g_string_free(ys, TRUE); diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index 581c8a440..74a0d829c 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -410,8 +410,8 @@ char* SPGuide::description(bool const verbose) const Inkscape::Util::Quantity x_q = Inkscape::Util::Quantity(this->point_on_line[X], "px"); Inkscape::Util::Quantity y_q = Inkscape::Util::Quantity(this->point_on_line[Y], "px"); - GString *position_string_x = g_string_new(x_q.string(namedview->doc_units).c_str()); - GString *position_string_y = g_string_new(y_q.string(namedview->doc_units).c_str()); + GString *position_string_x = g_string_new(x_q.string(namedview->display_units).c_str()); + GString *position_string_y = g_string_new(y_q.string(namedview->display_units).c_str()); gchar *shortcuts = g_strdup_printf("; %s", _("<b>Shift+drag</b> to rotate, <b>Ctrl+drag</b> to move origin, <b>Del</b> to delete")); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 019d15162..f059ab531 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -58,8 +58,8 @@ static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem); typedef std::list<std::string> HRefList; -static std::string patheffectlist_write_svg(PathEffectList const & list); -static std::string hreflist_write_svg(HRefList const & list); +static std::string patheffectlist_svg_string(PathEffectList const & list); +static std::string hreflist_svg_string(HRefList const & list); SPLPEItem::SPLPEItem() : SPItem() @@ -195,8 +195,7 @@ void SPLPEItem::modified(unsigned int flags) { Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { if (flags & SP_OBJECT_WRITE_EXT) { if ( hasPathEffect() ) { - std::string href = patheffectlist_write_svg(*this->path_effect_list); - repr->setAttribute("inkscape:path-effect", href.c_str()); + repr->setAttribute("inkscape:path-effect", patheffectlist_svg_string(*this->path_effect_list)); } else { repr->setAttribute("inkscape:path-effect", NULL); } @@ -418,9 +417,9 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem) } } -void SPLPEItem::addPathEffect(gchar *value, bool reset) +void SPLPEItem::addPathEffect(std::string value, bool reset) { - if (value) { + if (!value.empty()) { // Apply the path effects here because in the casse of a group, lpe->resetDefaults // needs that all the subitems have their effects applied sp_lpe_item_update_patheffect(this, false, true); @@ -434,10 +433,9 @@ void SPLPEItem::addPathEffect(gchar *value, bool reset) { hreflist.push_back( std::string((*it)->lpeobject_href) ); } - hreflist.push_back( std::string(value) ); - std::string hrefs = hreflist_write_svg(hreflist); + hreflist.push_back(value); // C++11: should be emplace_back std::move'd (also the reason why passed by value to addPathEffect) - this->getRepr()->setAttribute("inkscape:path-effect", hrefs.c_str()); + this->getRepr()->setAttribute("inkscape:path-effect", hreflist_svg_string(hreflist)); // Make sure that ellipse is stored as <svg:path> if( SP_IS_GENERICELLIPSE(this)) { @@ -501,13 +499,7 @@ void SPLPEItem::removeCurrentPathEffect(bool keep_paths) } PathEffectList new_list = *this->path_effect_list; new_list.remove(lperef); //current lpe ref is always our 'own' pointer from the path_effect_list - std::string r = patheffectlist_write_svg(new_list); - - if (!r.empty()) { - this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); - } else { - this->getRepr()->setAttribute("inkscape:path-effect", NULL); - } + this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); if (!keep_paths) { // Make sure that ellipse is stored as <svg:circle> or <svg:ellipse> if possible. @@ -551,8 +543,8 @@ void SPLPEItem::downCurrentPathEffect() std::iter_swap(cur_it, down_it); } } - std::string r = patheffectlist_write_svg(new_list); - this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); + + this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); sp_lpe_item_cleanup_original_path_recursive(this); } @@ -570,9 +562,8 @@ void SPLPEItem::upCurrentPathEffect() --up_it; std::iter_swap(cur_it, up_it); } - std::string r = patheffectlist_write_svg(new_list); - this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); + this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); sp_lpe_item_cleanup_original_path_recursive(this); } @@ -862,16 +853,16 @@ void SPLPEItem::remove_child(Inkscape::XML::Node * child) { SPItem::remove_child(child); } -static std::string patheffectlist_write_svg(PathEffectList const & list) +static std::string patheffectlist_svg_string(PathEffectList const & list) { HRefList hreflist; for (PathEffectList::const_iterator it = list.begin(); it != list.end(); ++it) { - hreflist.push_back( std::string((*it)->lpeobject_href) ); + hreflist.push_back( std::string((*it)->lpeobject_href) ); // C++11: use emplace_back } - return hreflist_write_svg(hreflist); + return hreflist_svg_string(hreflist); } /** @@ -881,7 +872,7 @@ static std::string patheffectlist_write_svg(PathEffectList const & list) * - populate the templist with the effects from the old list that you want to have and their order * - call this function with temp list as param */ -static std::string hreflist_write_svg(HRefList const & list) +static std::string hreflist_svg_string(HRefList const & list) { std::string r; bool semicolon_first = false; @@ -968,8 +959,7 @@ void SPLPEItem::replacePathEffects( std::vector<LivePathEffectObject const *> co } } - std::string r = hreflist_write_svg(hreflist); - this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); + this->getRepr()->setAttribute("inkscape:path-effect", hreflist_svg_string(hreflist)); } /** diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 9c052b7b1..902271430 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -15,6 +15,7 @@ */ #include <list> +#include <string> #include "sp-item.h" #define SP_LPE_ITEM(obj) (dynamic_cast<SPLPEItem*>((SPObject*)obj)) @@ -88,7 +89,7 @@ public: bool setCurrentPathEffect(Inkscape::LivePathEffect::LPEObjectReference* lperef); void removeCurrentPathEffect(bool keep_paths); void removeAllPathEffects(bool keep_paths); - void addPathEffect(char *value, bool reset); + void addPathEffect(std::string value, bool reset); void addPathEffect(LivePathEffectObject * new_lpeobj); void apply_to_mask(SPItem * item); void apply_to_clippath(SPItem * item); diff --git a/src/sp-marker.cpp b/src/sp-marker.cpp index e955594ab..1c13a54e6 100644 --- a/src/sp-marker.cpp +++ b/src/sp-marker.cpp @@ -168,9 +168,12 @@ void SPMarker::set(unsigned int key, const gchar* value) { } else if (!strcmp (value, "auto-start-reverse")) { this->orient_mode = MARKER_ORIENT_AUTO_START_REVERSE; this->orient_set = TRUE; - } else if (sp_svg_number_read_f (value, &this->orient)) { - this->orient_mode = MARKER_ORIENT_ANGLE; - this->orient_set = TRUE; + } else { + orient.readOrUnset(value); + if (orient._set) { + this->orient_mode = MARKER_ORIENT_ANGLE; + this->orient_set = orient._set; + } } } @@ -273,7 +276,7 @@ Inkscape::XML::Node* SPMarker::write(Inkscape::XML::Document *xml_doc, Inkscape: } else if (this->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { repr->setAttribute("orient", "auto-start-reverse"); } else { - sp_repr_set_css_double(repr, "orient", this->orient); + sp_repr_set_css_double(repr, "orient", this->orient.computed); } } else { repr->setAttribute("orient", NULL); @@ -394,7 +397,7 @@ sp_marker_show_instance ( SPMarker *marker, Inkscape::DrawingItem *parent, m = base; } else { /* fixme: Orient units (Lauris) */ - m = Geom::Rotate::from_degrees(marker->orient); + m = Geom::Rotate::from_degrees(marker->orient.computed); m *= Geom::Translate(base.translation()); } if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { diff --git a/src/sp-marker.h b/src/sp-marker.h index b58523251..548a6f6f0 100644 --- a/src/sp-marker.h +++ b/src/sp-marker.h @@ -28,6 +28,7 @@ struct SPMarkerView; #include "enums.h" #include "svg/svg-length.h" +#include "svg/svg-angle.h" #include "sp-item-group.h" #include "uri-references.h" #include "viewbox.h" @@ -58,7 +59,7 @@ public: /* orient */ unsigned int orient_set : 1; markerOrient orient_mode : 2; - float orient; + SVGAngle orient; /* Private views */ SPMarkerView *views; diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index b68421dc6..09d383e3c 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -76,7 +76,9 @@ SPNamedView::SPNamedView() : SPObjectGroup(), snap_manager(this) { this->window_x = 0; this->cy = 0; this->window_y = 0; - this->doc_units = NULL; + this->svg_units = unit_table.getUnit("px"); // legacy behavior: if no viewbox present, default to 'px' units + this->display_units = NULL; + this->page_size_units = NULL; this->pagecolor = 0; this->cx = 0; this->pageshadow = 0; @@ -262,6 +264,14 @@ void SPNamedView::build(SPDocument *document, Inkscape::XML::Node *repr) { // backwards compatibility with grid settings (pre 0.46) sp_namedview_generate_old_grid(this, document, repr); + + // If viewbox defined: try to calculate the SVG unit from document width and viewbox + if (document->getRoot()->viewBox_set) { + Inkscape::Util::Quantity svgwidth = document->getWidth(); + Geom::Rect viewbox = document->getRoot()->viewBox; + double factor = svgwidth.value(unit_table.primary(Inkscape::Util::UNIT_TYPE_LINEAR)) / viewbox.width(); + svg_units = unit_table.findUnit(factor, Inkscape::Util::UNIT_TYPE_LINEAR); + } } void SPNamedView::release() { @@ -540,22 +550,13 @@ void SPNamedView::set(unsigned int key, const gchar* value) { this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_INKSCAPE_DOCUMENT_UNITS: { - /* The default unit if the document doesn't override this: e.g. for files saved as + /* The default display unit if the document doesn't override this: e.g. for files saved as * `plain SVG', or non-inkscape files, or files created by an inkscape 0.40 & * earlier. * - * Here we choose `px': useful for screen-destined SVGs, and fewer bug reports - * about "not the same numbers as what's in the SVG file" (at least for documents - * without a viewBox attribute on the root <svg> element). Similarly, it's also - * the most reliable unit (i.e. least likely to be wrong in different viewing - * conditions) for viewBox-less SVG files given that it's the unit that inkscape - * uses for all coordinates. + * Note that these units are not the same as the units used for the values in SVG! * - * For documents that do have a viewBox attribute on the root <svg> element, it - * might be better if we used either viewBox coordinates or if we used the unit of - * say the width attribute of the root <svg> element. However, these pose problems - * in that they aren't in general absolute units as currently required by - * doc_units. + * We default to `px'. */ static Inkscape::Util::Unit const *px = unit_table.getUnit("px"); Inkscape::Util::Unit const *new_unit = px; @@ -576,7 +577,7 @@ void SPNamedView::set(unsigned int key, const gchar* value) { /* fixme: Don't use g_log (see above). */ } } - this->doc_units = new_unit; + this->display_units = new_unit; this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; } @@ -1133,7 +1134,13 @@ double SPNamedView::getMarginLength(gchar const * const key, */ Inkscape::Util::Unit const * SPNamedView::getDefaultUnit() const { - return doc_units ? doc_units : unit_table.getUnit("pt"); + return display_units ? display_units : unit_table.getUnit("pt"); +} + +Inkscape::Util::Unit const & SPNamedView::getSVGUnit() const +{ + assert(svg_units); + return *svg_units; } /** diff --git a/src/sp-namedview.h b/src/sp-namedview.h index 4746b2962..64bf14a8b 100644 --- a/src/sp-namedview.h +++ b/src/sp-namedview.h @@ -61,7 +61,8 @@ public: GSList * grids; bool grids_visible; - Inkscape::Util::Unit const *doc_units; + Inkscape::Util::Unit const *svg_units; // Units used for the values in SVG + Inkscape::Util::Unit const *display_units; // Units used for the UI (*not* the same as units of SVG coordinates) Inkscape::Util::Unit const *page_size_units; // Only used in "Custom size" part of Document Properties dialog GQuark default_layer_id; @@ -86,6 +87,7 @@ public: unsigned int getViewCount(); GSList const *getViewList() const; Inkscape::Util::Unit const * getDefaultUnit() const; + Inkscape::Util::Unit const & getSVGUnit() const; void translateGuides(Geom::Translate const &translation); void translateGrids(Geom::Translate const &translation); diff --git a/src/sp-object.cpp b/src/sp-object.cpp index 024fce85a..4e45eb824 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -1254,6 +1254,16 @@ void SPObject::setAttribute(gchar const *key, gchar const *value, SPException *e //XML Tree being used here. getRepr()->setAttribute(key, value, false); } +void SPObject::setAttribute(char const *key, Glib::ustring const &value, SPException *ex) +{ + setAttribute(key, value.empty() ? NULL : value.c_str(), ex); +} +void SPObject::setAttribute(Glib::ustring const &key, Glib::ustring const &value, SPException *ex) +{ + setAttribute( key.empty() ? NULL : key.c_str(), + value.empty() ? NULL : value.c_str(), ex); +} + void SPObject::removeAttribute(gchar const *key, SPException *ex) { diff --git a/src/sp-object.h b/src/sp-object.h index 575198f36..d08add0bf 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -67,6 +67,9 @@ struct Document; } } +namespace Glib { + class ustring; +} typedef enum { SP_NO_EXCEPTION, @@ -703,7 +706,9 @@ public: */ void setKeyValue(unsigned int key, char const *value); - void setAttribute(char const *key, char const *value, SPException *ex=NULL); + void setAttribute( char const *key, char const *value, SPException *ex=NULL); + void setAttribute( char const *key, Glib::ustring const &value, SPException *ex=NULL); + void setAttribute(Glib::ustring const &key, Glib::ustring const &value, SPException *ex=NULL); /** * Read value of key attribute from XML node into object. diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index 8b7e735e0..6d240fbf5 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -434,7 +434,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox tr = Geom::Rotate::from_degrees( 180.0 ) * tr; } else if (_marker[i]->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); - tr = Geom::Rotate::from_degrees(_marker[i]->orient) * Geom::Translate(transl); + tr = Geom::Rotate::from_degrees(_marker[i]->orient.computed) * Geom::Translate(transl); } if (_marker[i]->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { @@ -472,7 +472,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(transl); } if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { @@ -502,7 +502,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(transl); } if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { @@ -525,7 +525,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(transl); } if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { @@ -560,7 +560,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(transl); } if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { diff --git a/src/sp-text.cpp b/src/sp-text.cpp index 93d81e47b..8922d3c73 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -362,7 +362,7 @@ gchar* SPText::description() const { char *n = xml_quote_strdup( style->font_family.value ); Inkscape::Util::Quantity q = Inkscape::Util::Quantity(style->font_size.computed, "px"); - GString *xs = g_string_new(q.string(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units).c_str()); + GString *xs = g_string_new(q.string(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->display_units).c_str()); char const *trunc = ""; Inkscape::Text::Layout const *layout = te_get_layout((SPItem *) this); diff --git a/src/svg/svg-color.cpp b/src/svg/svg-color.cpp index c9f22f8a4..693094048 100644 --- a/src/svg/svg-color.cpp +++ b/src/svg/svg-color.cpp @@ -32,8 +32,8 @@ #include "svg-color.h" #include "svg-icc-color.h" -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) #include "color.h" +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) #include "color-profile.h" #include "document.h" #include "inkscape.h" diff --git a/src/svg/svg-length.cpp b/src/svg/svg-length.cpp index b9b475f4b..ea235b2e4 100644 --- a/src/svg/svg-length.cpp +++ b/src/svg/svg-length.cpp @@ -520,7 +520,8 @@ gchar const *sp_svg_length_get_css_units(SVGLength::Unit unit) case SVGLength::MM: return "mm"; case SVGLength::CM: return "cm"; case SVGLength::INCH: return "in"; - case SVGLength::FOOT: return ""; // Does not have a "foot" unit string in the SVG spec + case SVGLength::FOOT: return ""; // Not in SVG/CSS specification. + case SVGLength::MITRE: return ""; // Not in SVG/CSS specification. case SVGLength::EM: return "em"; case SVGLength::EX: return "ex"; case SVGLength::PERCENT: return "%"; @@ -539,6 +540,8 @@ std::string sp_svg_length_write_with_units(SVGLength const &length) os << 100*length.value << sp_svg_length_get_css_units(length.unit); } else if (length.unit == SVGLength::FOOT) { os << 12*length.value << sp_svg_length_get_css_units(SVGLength::INCH); + } else if (length.unit == SVGLength::MITRE) { + os << 100*length.value << sp_svg_length_get_css_units(SVGLength::CM); } else { os << length.value << sp_svg_length_get_css_units(length.unit); } diff --git a/src/svg/svg-length.h b/src/svg/svg-length.h index c34905d07..1e6b4c96c 100644 --- a/src/svg/svg-length.h +++ b/src/svg/svg-length.h @@ -28,6 +28,7 @@ public: CM, INCH, FOOT, + MITRE, EM, EX, PERCENT, diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index d538ea5c5..37881d4ae 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -1093,7 +1093,7 @@ CloneTiler::CloneTiler () : // unitmenu unit_menu = new Inkscape::UI::Widget::UnitMenu(); unit_menu->setUnitType(Inkscape::Util::UNIT_TYPE_LINEAR); - unit_menu->setUnit(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units->abbr); + unit_menu->setUnit(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->display_units->abbr); unitChangedConn = unit_menu->signal_changed().connect(sigc::mem_fun(*this, &CloneTiler::clonetiler_unit_changed)); { @@ -2251,7 +2251,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) clonetiler_remove (NULL, dlg, false); - double scale_units = Inkscape::Util::Quantity::convert(1, "px", sp_desktop_document(desktop)->getDefaultUnit()); + double scale_units = Inkscape::Util::Quantity::convert(1, "px", &sp_desktop_document(desktop)->getSVGUnit()); double shiftx_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_per_i", 0, -10000, 10000); double shifty_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shifty_per_i", 0, -10000, 10000); diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 084a1e98d..13ee8a6c6 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1480,8 +1480,8 @@ void DocumentProperties::update() _rcb_antialias.set_xml_target(root->getRepr(), dt->getDocument()); _rcb_antialias.setActive(root->style->shape_rendering.computed != SP_CSS_SHAPE_RENDERING_CRISPEDGES); - if (nv->doc_units) { - _rum_deflt.setUnit (nv->doc_units->abbr); + if (nv->display_units) { + _rum_deflt.setUnit (nv->display_units->abbr); } double doc_w = sp_desktop_document(dt)->getRoot()->width.value; diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index ba30c8e6b..1ebd1fc7c 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -206,7 +206,7 @@ Export::Export (void) : SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { - unit_selector.setUnit(sp_desktop_namedview(desktop)->doc_units->abbr); + unit_selector.setUnit(sp_desktop_namedview(desktop)->display_units->abbr); } unitChangedConn = unit_selector.signal_changed().connect(sigc::mem_fun(*this, &Export::onUnitChanged)); unitbox.pack_end(unit_selector, false, false, 0); diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index 4519a905f..221f9a1c0 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -216,8 +216,8 @@ void GuidelinePropertiesDialog::_setup() { /* fixme: We should allow percents here too, as percents of the canvas size */ _unit_menu.setUnitType(UNIT_TYPE_LINEAR); _unit_menu.setUnit("px"); - if (_desktop->namedview->doc_units) { - _unit_menu.setUnit( _desktop->namedview->doc_units->abbr ); + if (_desktop->namedview->display_units) { + _unit_menu.setUnit( _desktop->namedview->display_units->abbr ); } _spin_angle.setUnit(_angle_unit_status); diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 87b698673..ed4b16008 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -461,7 +461,7 @@ void InkscapePreferences::initPageTools() _page_text.add_line( false, _("Text size unit type:"), _font_unit_type, "", _("Set the type of unit used in the text toolbar and text dialogs"), false); _font_output_px.init ( _("Always output text size in pixels (px)"), "/options/font/textOutputPx", true); - _page_text.add_line( false, "", _font_output_px, "", _("Always convert the text size units above into pixels (px) before saving to file")); +// _page_text.add_line( false, "", _font_output_px, "", _("Always convert the text size units above into pixels (px) before saving to file")); this->AddNewObjectsStyle(_page_text, "/tools/text"); diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index eb3857ee7..178c32c38 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -475,9 +475,13 @@ LivePathEffectEditor::onAdd() // run sp_selection_clone_original_path_lpe sp_selection_clone_original_path_lpe(current_desktop); + SPItem *new_item = sel->singleItem(); - new_item->getRepr()->setAttribute("id", id); - new_item->getRepr()->setAttribute("transform", transform); + // Check that the cloning was successful. We don't want to change the ID of the original referenced path! + if (new_item && (new_item != orig)) { + new_item->getRepr()->setAttribute("id", id); + new_item->getRepr()->setAttribute("transform", transform); + } g_free(id); g_free(transform); diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp index 43f0e8683..2c6692777 100644 --- a/src/ui/dialog/transformation.cpp +++ b/src/ui/dialog/transformation.cpp @@ -206,8 +206,8 @@ void Transformation::layoutPageMove() // Setting default unit to document unit SPDesktop *dt = getDesktop(); SPNamedView *nv = sp_desktop_namedview(dt); - if (nv->doc_units) { - _units_move.setUnit(nv->doc_units->abbr); + if (nv->display_units) { + _units_move.setUnit(nv->display_units->abbr); } _scalar_move_horizontal.initScalar(-1e6, 1e6); diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 8a1ca0b90..8c22f7c6e 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -566,9 +566,9 @@ Glib::ustring Handle::_getDragTip(GdkEventMotion */*event*/) const Inkscape::Util::Quantity x_q = Inkscape::Util::Quantity(dist[Geom::X], "px"); Inkscape::Util::Quantity y_q = Inkscape::Util::Quantity(dist[Geom::Y], "px"); Inkscape::Util::Quantity len_q = Inkscape::Util::Quantity(length(), "px"); - GString *x = g_string_new(x_q.string(_desktop->namedview->doc_units).c_str()); - GString *y = g_string_new(y_q.string(_desktop->namedview->doc_units).c_str()); - GString *len = g_string_new(len_q.string(_desktop->namedview->doc_units).c_str()); + GString *x = g_string_new(x_q.string(_desktop->namedview->display_units).c_str()); + GString *y = g_string_new(y_q.string(_desktop->namedview->display_units).c_str()); + GString *len = g_string_new(len_q.string(_desktop->namedview->display_units).c_str()); Glib::ustring ret = format_tip(C_("Path handle tip", "Move handle by %s, %s; angle %.2f°, length %s"), x->str, y->str, angle, len->str); g_string_free(x, TRUE); @@ -1490,8 +1490,8 @@ Glib::ustring Node::_getDragTip(GdkEventMotion */*event*/) const Inkscape::Util::Quantity x_q = Inkscape::Util::Quantity(dist[Geom::X], "px"); Inkscape::Util::Quantity y_q = Inkscape::Util::Quantity(dist[Geom::Y], "px"); - GString *x = g_string_new(x_q.string(_desktop->namedview->doc_units).c_str()); - GString *y = g_string_new(y_q.string(_desktop->namedview->doc_units).c_str()); + GString *x = g_string_new(x_q.string(_desktop->namedview->display_units).c_str()); + GString *y = g_string_new(y_q.string(_desktop->namedview->display_units).c_str()); Glib::ustring ret = format_tip(C_("Path node tip", "Move node by %s, %s"), x->str, y->str); g_string_free(x, TRUE); g_string_free(y, TRUE); diff --git a/src/ui/tools/arc-tool.cpp b/src/ui/tools/arc-tool.cpp index 4f64ade25..9c3195a42 100644 --- a/src/ui/tools/arc-tool.cpp +++ b/src/ui/tools/arc-tool.cpp @@ -405,8 +405,8 @@ void ArcTool::drag(Geom::Point pt, guint state) { Inkscape::Util::Quantity rdimx_q = Inkscape::Util::Quantity(rdimx, "px"); Inkscape::Util::Quantity rdimy_q = Inkscape::Util::Quantity(rdimy, "px"); - GString *xs = g_string_new(rdimx_q.string(desktop->namedview->doc_units).c_str()); - GString *ys = g_string_new(rdimy_q.string(desktop->namedview->doc_units).c_str()); + GString *xs = g_string_new(rdimx_q.string(desktop->namedview->display_units).c_str()); + GString *ys = g_string_new(rdimy_q.string(desktop->namedview->display_units).c_str()); if (state & GDK_CONTROL_MASK) { int ratio_x, ratio_y; diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index bd84e0efb..32702a17e 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -256,7 +256,7 @@ static void spdc_apply_powerstroke_shape(const std::vector<Geom::Point> & points std::ostringstream s; s.imbue(std::locale::classic()); - s << "0," << stroke_width / 2.; + s << points[0][Geom::X] << "," << stroke_width / 2.; // write powerstroke parameters: lpe->getRepr()->setAttribute("start_linecap_type", "zerowidth"); diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 92937a135..fbcdf6142 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1366,7 +1366,7 @@ void PenTool::_setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_t Geom::Point rel = p - this->p[pc_point_to_compare]; Inkscape::Util::Quantity q = Inkscape::Util::Quantity(Geom::L2(rel), "px"); - GString *dist = g_string_new(q.string(desktop->namedview->doc_units).c_str()); + GString *dist = g_string_new(q.string(desktop->namedview->display_units).c_str()); double angle = atan2(rel[Geom::Y], rel[Geom::X]) * 180 / M_PI; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/options/compassangledisplay/value", 0) != 0) { diff --git a/src/ui/tools/rect-tool.cpp b/src/ui/tools/rect-tool.cpp index de91dcff4..67df0d9a5 100644 --- a/src/ui/tools/rect-tool.cpp +++ b/src/ui/tools/rect-tool.cpp @@ -422,8 +422,8 @@ void RectTool::drag(Geom::Point const pt, guint state) { Inkscape::Util::Quantity rdimx_q = Inkscape::Util::Quantity(rdimx, "px"); Inkscape::Util::Quantity rdimy_q = Inkscape::Util::Quantity(rdimy, "px"); - GString *xs = g_string_new(rdimx_q.string(desktop->namedview->doc_units).c_str()); - GString *ys = g_string_new(rdimy_q.string(desktop->namedview->doc_units).c_str()); + GString *xs = g_string_new(rdimx_q.string(desktop->namedview->display_units).c_str()); + GString *ys = g_string_new(rdimy_q.string(desktop->namedview->display_units).c_str()); if (state & GDK_CONTROL_MASK) { int ratio_x, ratio_y; diff --git a/src/ui/tools/spiral-tool.cpp b/src/ui/tools/spiral-tool.cpp index 18c3e4e2d..31c4e8829 100644 --- a/src/ui/tools/spiral-tool.cpp +++ b/src/ui/tools/spiral-tool.cpp @@ -395,7 +395,7 @@ void SpiralTool::drag(Geom::Point const &p, guint state) { /* status text */ Inkscape::Util::Quantity q = Inkscape::Util::Quantity(rad, "px"); - GString *rads = g_string_new(q.string(desktop->namedview->doc_units).c_str()); + GString *rads = g_string_new(q.string(desktop->namedview->display_units).c_str()); this->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("<b>Spiral</b>: radius %s, angle %5g°; with <b>Ctrl</b> to snap angle"), rads->str, sp_round((arg + 2.0*M_PI*this->spiral->revo)*180/M_PI, 0.0001)); diff --git a/src/ui/tools/star-tool.cpp b/src/ui/tools/star-tool.cpp index 7604ba04e..b5544d263 100644 --- a/src/ui/tools/star-tool.cpp +++ b/src/ui/tools/star-tool.cpp @@ -411,7 +411,7 @@ void StarTool::drag(Geom::Point p, guint state) /* status text */ Inkscape::Util::Quantity q = Inkscape::Util::Quantity(r1, "px"); - GString *rads = g_string_new(q.string(desktop->namedview->doc_units).c_str()); + GString *rads = g_string_new(q.string(desktop->namedview->display_units).c_str()); this->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, ( this->isflatsided? _("<b>Polygon</b>: radius %s, angle %5g°; with <b>Ctrl</b> to snap angle") diff --git a/src/ui/tools/text-tool.cpp b/src/ui/tools/text-tool.cpp index a72748733..578add843 100644 --- a/src/ui/tools/text-tool.cpp +++ b/src/ui/tools/text-tool.cpp @@ -590,8 +590,8 @@ bool TextTool::root_handler(GdkEvent* event) { // status text Inkscape::Util::Quantity x_q = Inkscape::Util::Quantity(fabs((p - this->p0)[Geom::X]), "px"); Inkscape::Util::Quantity y_q = Inkscape::Util::Quantity(fabs((p - this->p0)[Geom::Y]), "px"); - GString *xs = g_string_new(x_q.string(desktop->namedview->doc_units).c_str()); - GString *ys = g_string_new(y_q.string(desktop->namedview->doc_units).c_str()); + GString *xs = g_string_new(x_q.string(desktop->namedview->display_units).c_str()); + GString *ys = g_string_new(y_q.string(desktop->namedview->display_units).c_str()); this->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("<b>Flowed text frame</b>: %s × %s"), xs->str, ys->str); g_string_free(xs, FALSE); diff --git a/src/ui/widget/page-sizer.cpp b/src/ui/widget/page-sizer.cpp index 32e357c57..b775b3c49 100644 --- a/src/ui/widget/page-sizer.cpp +++ b/src/ui/widget/page-sizer.cpp @@ -313,8 +313,8 @@ PageSizer::PageSizer(Registry & _wr) _wr.setUpdating (true); if (nv->page_size_units) { _dimensionUnits.setUnit(nv->page_size_units->abbr); - } else if (nv->doc_units) { - _dimensionUnits.setUnit(nv->doc_units->abbr); + } else if (nv->display_units) { + _dimensionUnits.setUnit(nv->display_units->abbr); } _wr.setUpdating (false); diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index d22c59aa4..aebef2c4e 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -498,7 +498,7 @@ SelectedStyle::setDesktop(SPDesktop *desktop) this ) )); - _sw_unit = sp_desktop_namedview(desktop)->doc_units; + _sw_unit = sp_desktop_namedview(desktop)->display_units; // Set the doc default unit active in the units list gint length = g_slist_length(_unit_mis); diff --git a/src/util/units.cpp b/src/util/units.cpp index 3d635e2d2..2c72ec3ae 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -16,11 +16,14 @@ #include <cmath> #include <cerrno> #include <iomanip> +#include <iostream> #include <glib.h> #include <glibmm/regex.h> #include <glibmm/fileutils.h> #include <glibmm/markup.h> +#include <2geom/coord.h> + #include "util/units.h" #include "path-prefix.h" #include "streq.h" @@ -44,6 +47,7 @@ enum UnitCode { UNIT_CODE_CM = MAKE_UNIT_CODE('c','m'), UNIT_CODE_IN = MAKE_UNIT_CODE('i','n'), UNIT_CODE_FT = MAKE_UNIT_CODE('f','t'), + UNIT_CODE_MT = MAKE_UNIT_CODE('m',' '), UNIT_CODE_EM = MAKE_UNIT_CODE('e','m'), UNIT_CODE_EX = MAKE_UNIT_CODE('e','x'), UNIT_CODE_PERCENT = MAKE_UNIT_CODE('%',0) @@ -71,6 +75,7 @@ unsigned const svg_length_lookup[] = { UNIT_CODE_CM, UNIT_CODE_IN, UNIT_CODE_FT, + UNIT_CODE_MT, UNIT_CODE_EM, UNIT_CODE_EX, UNIT_CODE_PERCENT @@ -279,6 +284,28 @@ Unit const *UnitTable::getUnit(SVGLength::Unit u) const return &_empty_unit; } +Unit const *UnitTable::findUnit(double factor, UnitType type) const +{ + const double eps = factor * 0.01; // allow for 1% deviation + + UnitCodeMap::const_iterator cit = _unit_map.begin(); + while (cit != _unit_map.end()) { + if (cit->second->type == type) { + if (Geom::are_near(cit->second->factor, factor, eps)) { + // unit found! + break; + } + } + ++cit; + } + + if (cit != _unit_map.end()) { + return cit->second; + } else { + return getUnit(_primary_unit[type]); + } +} + Quantity UnitTable::parseQuantity(Glib::ustring const &q) const { Glib::MatchInfo match_info; diff --git a/src/util/units.h b/src/util/units.h index efe1dbec7..13777fd1b 100644 --- a/src/util/units.h +++ b/src/util/units.h @@ -141,6 +141,9 @@ public: /** Retrieve a given unit based on its string identifier */ Unit const *getUnit(Glib::ustring const &name) const; Unit const *getUnit(char const *name) const; + + /** Try to find a unit based on its conversion factor to the primary */ + Unit const *findUnit(double factor, UnitType type) const; /** Retrieve a given unit based on its SVGLength unit */ Unit const *getUnit(SVGLength::Unit u) const; diff --git a/src/verbs.cpp b/src/verbs.cpp index 577407412..bafb6f89b 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -1860,7 +1860,7 @@ void ZoomVerb::perform(SPAction *action, void *data) double zcorr = 1.0; Glib::ustring abbr = prefs->getString("/options/zoomcorrection/unit"); - if (dt->namedview->doc_units && dt->namedview->doc_units->abbr == abbr) + if (dt->namedview->display_units && (dt->namedview->display_units->abbr == abbr)) zcorr = prefs->getDouble("/options/zoomcorrection/value", 1.0); Geom::Rect const d = dt->get_display_area(); diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index ef3b29478..989b060c9 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -1665,7 +1665,7 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview) { SPDesktopWidget *dtw = static_cast<SPDesktopWidget*>(g_object_new(SP_TYPE_DESKTOP_WIDGET, NULL)); - dtw->dt2r = 1. / namedview->doc_units->factor; + dtw->dt2r = 1. / namedview->display_units->factor; dtw->ruler_origin = Geom::Point(0,0); //namedview->gridorigin; Why was the grid origin used here? @@ -1737,7 +1737,7 @@ void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags) SPNamedView *nv=SP_NAMEDVIEW(obj); if (flags & SP_OBJECT_MODIFIED_FLAG) { - this->dt2r = 1. / nv->doc_units->factor; + this->dt2r = 1. / nv->display_units->factor; this->ruler_origin = Geom::Point(0,0); //nv->gridorigin; Why was the grid origin used here? sp_ruler_set_unit(SP_RULER (this->vruler), nv->getDefaultUnit()); @@ -1771,14 +1771,14 @@ void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags) if (tracker == NULL) // it's null when inkscape is first opened continue; - tracker->setActiveUnit( nv->doc_units ); + tracker->setActiveUnit( nv->display_units ); } // grandchildren } // if child is a container } // children } // if aux_toolbox is a container - gtk_widget_set_tooltip_text(this->hruler_box, gettext(nv->doc_units->name_plural.c_str())); - gtk_widget_set_tooltip_text(this->vruler_box, gettext(nv->doc_units->name_plural.c_str())); + gtk_widget_set_tooltip_text(this->hruler_box, gettext(nv->display_units->name_plural.c_str())); + gtk_widget_set_tooltip_text(this->vruler_box, gettext(nv->display_units->name_plural.c_str())); sp_desktop_widget_update_rulers(this); ToolboxFactory::updateSnapToolbox(this->desktop, 0, this->snap_toolbox); diff --git a/src/widgets/lpe-toolbar.cpp b/src/widgets/lpe-toolbar.cpp index a85f3ae78..c6da46956 100644 --- a/src/widgets/lpe-toolbar.cpp +++ b/src/widgets/lpe-toolbar.cpp @@ -280,7 +280,7 @@ static void lpetool_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBas void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); - tracker->setActiveUnit(sp_desktop_namedview(desktop)->doc_units); + tracker->setActiveUnit(sp_desktop_namedview(desktop)->display_units); g_object_set_data(holder, "tracker", tracker); Unit const *unit = tracker->getActiveUnit(); g_return_if_fail(unit != NULL); diff --git a/src/widgets/node-toolbar.cpp b/src/widgets/node-toolbar.cpp index 467325d08..1224ab355 100644 --- a/src/widgets/node-toolbar.cpp +++ b/src/widgets/node-toolbar.cpp @@ -330,7 +330,7 @@ static void node_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); - Unit doc_units = *sp_desktop_namedview(desktop)->doc_units; + Unit doc_units = *sp_desktop_namedview(desktop)->display_units; tracker->setActiveUnit(&doc_units); g_object_set_data( holder, "tracker", tracker ); diff --git a/src/widgets/rect-toolbar.cpp b/src/widgets/rect-toolbar.cpp index b6b7e435d..5356ebb0d 100644 --- a/src/widgets/rect-toolbar.cpp +++ b/src/widgets/rect-toolbar.cpp @@ -109,7 +109,7 @@ static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const * for (GSList const *items = selection->itemList(); items != NULL; items = items->next) { if (SP_IS_RECT(items->data)) { if (gtk_adjustment_get_value(adj) != 0) { - (SP_RECT(items->data)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, sp_desktop_namedview(desktop)->doc_units)); + (SP_RECT(items->data)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, sp_desktop_namedview(desktop)->svg_units)); } else { SP_OBJECT(items->data)->getRepr()->setAttribute(value_name, NULL); } @@ -181,7 +181,7 @@ static void rect_tb_event_attr_changed(Inkscape::XML::Node * /*repr*/, gchar con UnitTracker* tracker = reinterpret_cast<UnitTracker*>( g_object_get_data( tbl, "tracker" ) ); Unit const *unit = tracker->getActiveUnit(); - Unit const *doc_unit = sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units; + Unit const *svg_unit = sp_desktop_namedview(SP_ACTIVE_DESKTOP)->svg_units; g_return_if_fail(unit != NULL); gpointer item = g_object_get_data( tbl, "item" ); @@ -190,28 +190,28 @@ static void rect_tb_event_attr_changed(Inkscape::XML::Node * /*repr*/, gchar con GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "rx" ) ); gdouble rx = SP_RECT(item)->getVisibleRx(); - gtk_adjustment_set_value(adj, Quantity::convert(rx, doc_unit, unit)); + gtk_adjustment_set_value(adj, Quantity::convert(rx, svg_unit, unit)); } { GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "ry" ) ); gdouble ry = SP_RECT(item)->getVisibleRy(); - gtk_adjustment_set_value(adj, Quantity::convert(ry, doc_unit, unit)); + gtk_adjustment_set_value(adj, Quantity::convert(ry, svg_unit, unit)); } { GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "width" ) ); gdouble width = SP_RECT(item)->getVisibleWidth(); - gtk_adjustment_set_value(adj, Quantity::convert(width, doc_unit, unit)); + gtk_adjustment_set_value(adj, Quantity::convert(width, svg_unit, unit)); } { GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "height" ) ); gdouble height = SP_RECT(item)->getVisibleHeight(); - gtk_adjustment_set_value(adj, Quantity::convert(height, doc_unit, unit)); + gtk_adjustment_set_value(adj, Quantity::convert(height, svg_unit, unit)); } } @@ -307,7 +307,7 @@ void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); //tracker->addUnit( SP_UNIT_PERCENT, 0 ); // fixme: add % meaning per cent of the width/height - tracker->setActiveUnit( sp_desktop_namedview(desktop)->doc_units ); + tracker->setActiveUnit( sp_desktop_namedview(desktop)->display_units ); g_object_set_data( holder, "tracker", tracker ); /* W */ diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index 5f107c5a8..e59d459b9 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -488,7 +488,7 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb // Create the units menu. UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); tracker->addUnit(unit_table.getUnit("%")); - tracker->setActiveUnit( sp_desktop_namedview(desktop)->doc_units ); + tracker->setActiveUnit( sp_desktop_namedview(desktop)->display_units ); g_object_set_data( G_OBJECT(spw), "tracker", tracker ); g_signal_connect( G_OBJECT(spw), "destroy", G_CALLBACK(destroy_tracker), spw ); diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 02dd5df6e..51880ba85 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -204,8 +204,8 @@ StrokeStyle::StrokeStyle() : unitSelector->addUnit(*unit_table.getUnit("%")); _old_unit = unitSelector->getUnit(); if (desktop) { - unitSelector->setUnit(sp_desktop_namedview(desktop)->doc_units->abbr); - _old_unit = sp_desktop_namedview(desktop)->doc_units; + unitSelector->setUnit(sp_desktop_namedview(desktop)->display_units->abbr); + _old_unit = sp_desktop_namedview(desktop)->display_units; } widthSpin->setUnitMenu(unitSelector); unitChangedConn = unitSelector->signal_changed().connect(sigc::mem_fun(*this, &StrokeStyle::unitChangedCB)); @@ -839,7 +839,7 @@ StrokeStyle::updateLine() // same width, or only one object; no sense to keep percent, switch to absolute Inkscape::Util::Unit const *tempunit = unitSelector->getUnit(); if (tempunit->type != Inkscape::Util::UNIT_TYPE_LINEAR) { - unitSelector->setUnit(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units->abbr); + unitSelector->setUnit(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->display_units->abbr); } } |
