diff --git a/src/attributes.cpp b/src/attributes.cpp index b2c676e8842ed58a26f3c8a2f4192b24235be579..e98f84700c08a8706b5d5481da15c375b509c2d0 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -137,6 +137,7 @@ static SPStyleProp const props[] = { /* SPImage */ {SP_ATTR_X, "x"}, {SP_ATTR_Y, "y"}, + {SP_ATTR_SVG_DPI, "inkscape:svg-dpi"}, /* SPPath */ {SP_ATTR_INKSCAPE_ORIGINAL_D, "inkscape:original-d"}, /* (Note: XML representation of connectors may change in future.) */ diff --git a/src/attributes.h b/src/attributes.h index caad42f71dfbe2065fb5930c73e6e2d7d42471f1..c840161386ba7f1a7d0c4c1ae42d841a180971f6 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -145,6 +145,7 @@ enum SPAttributeEnum { /* SPImage, SPRect, etc. */ SP_ATTR_X, SP_ATTR_Y, + SP_ATTR_SVG_DPI, /* SPPath */ // SP_ATTR_D, Promoted to property in SVG 2 SP_ATTR_INKSCAPE_ORIGINAL_D, diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index e34e4cd6b78d5e5f2016f96e99050fed529adc63..7279ac05233bf0b4f71c121174f413dd452087b3 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -207,7 +207,7 @@ Pixbuf::~Pixbuf() } } -Pixbuf *Pixbuf::create_from_data_uri(gchar const *uri_data) +Pixbuf *Pixbuf::create_from_data_uri(gchar const *uri_data, char const *svgdpi) { Pixbuf *pixbuf = nullptr; @@ -310,7 +310,11 @@ Pixbuf *Pixbuf::create_from_data_uri(gchar const *uri_data) return nullptr; } Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - const double dpi = prefs->getDouble("/dialogs/import/defaultxdpi/value", 96.0); + double dpi = prefs->getDouble("/dialogs/import/defaultxdpi/value", 96.0); + if (svgdpi && atof(svgdpi) > 0) { + dpi = atof(svgdpi); + } + std::cout << dpi << "dpi" << std::endl; // Get the size of the document Inkscape::Util::Quantity svgWidth = svgDoc->getWidth(); Inkscape::Util::Quantity svgHeight = svgDoc->getHeight(); @@ -338,7 +342,7 @@ Pixbuf *Pixbuf::create_from_data_uri(gchar const *uri_data) return pixbuf; } -Pixbuf *Pixbuf::create_from_file(std::string const &fn) +Pixbuf *Pixbuf::create_from_file(std::string const &fn, char const *svgdpi) { Pixbuf *pb = nullptr; // test correctness of filename @@ -350,7 +354,6 @@ Pixbuf *Pixbuf::create_from_file(std::string const &fn) if (val == 0 && stdir.st_mode & S_IFDIR){ return nullptr; } - // we need to load the entire file into memory, // since we'll store it as MIME data gchar *data = nullptr; @@ -383,7 +386,11 @@ Pixbuf *Pixbuf::create_from_file(std::string const &fn) return nullptr; } Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - const double dpi = prefs->getDouble("/dialogs/import/defaultxdpi/value", 96.0); + double dpi = prefs->getDouble("/dialogs/import/defaultxdpi/value", 96.0); + if (svgdpi && atof(svgdpi) > 0) { + dpi = atof(svgdpi); + } + std::cout << dpi << "dpi" << std::endl; // Get the size of the document Inkscape::Util::Quantity svgWidth = svgDoc->getWidth(); Inkscape::Util::Quantity svgHeight = svgDoc->getHeight(); diff --git a/src/display/cairo-utils.h b/src/display/cairo-utils.h index bada170ca1b51fa316cb058c6d046e93158f21fe..256bda94c3bb34de4e7df20e4dad50ec0a0ecd64 100644 --- a/src/display/cairo-utils.h +++ b/src/display/cairo-utils.h @@ -117,10 +117,10 @@ public: PixelFormat pixelFormat() const { return _pixel_format; } void ensurePixelFormat(PixelFormat fmt); - static Pixbuf *create_from_data_uri(gchar const *uri); - static Pixbuf *create_from_file(std::string const &fn); + static Pixbuf *create_from_data_uri(gchar const *uri, char const *svgdpi = NULL); + static Pixbuf *create_from_file(std::string const &fn, char const *svgddpi = NULL); -private: + private: void _ensurePixelsARGB32(); void _ensurePixelsPixbuf(); void _forceAlpha(); diff --git a/src/extension/internal/svg.cpp b/src/extension/internal/svg.cpp index 189ef3c58588edb21f88f3e1bd198404214b8d3d..d39f5a96039306a4eccadbc661d87694aa595e57 100644 --- a/src/extension/internal/svg.cpp +++ b/src/extension/internal/svg.cpp @@ -142,6 +142,7 @@ Svg::init() "<_option value='embed' >" N_("Embed the SVG file in a image tag (not editable in this document)") "\n" "<_option value='link' >" N_("Link the SVG file in a image tag (not editable in this document).") "\n" "\n" + "96.00\n" "\n" "<_option value='auto' >" N_("None (auto)") "\n" "<_option value='optimizeQuality' >" N_("Smooth (optimizeQuality)") "\n" @@ -208,7 +209,8 @@ Svg::open (Inkscape::Extension::Input *mod, const gchar *uri) Glib::ustring link_svg = prefs->getString("/dialogs/import/link_svg"); Glib::ustring scale = prefs->getString("/dialogs/import/scale"); bool is_import = false; - if (strcmp(prefs->getString("/options/openmethod/value").c_str(), "import") == 0) { + if (strcmp(prefs->getString("/options/openmethod/value").c_str(), "done") == 0 || + strcmp(prefs->getString("/options/openmethod/value").c_str(), "import") == 0) { is_import = true; } if(INKSCAPE.use_gui() && is_import && ask) { @@ -243,6 +245,8 @@ Svg::open (Inkscape::Extension::Input *mod, const gchar *uri) // Added 11 Feb 2014 as we now honor "preserveAspectRatio" and this is // what Inkscaper's expect. image_node->setAttribute("preserveAspectRatio", "none"); + Glib::ustring svgdpi = Glib::ustring::format(mod->get_param_float("svgdpi")); + image_node->setAttribute("inkscape:svg-dpi", svgdpi.c_str()); image_node->setAttribute("width", Glib::ustring::format(width)); image_node->setAttribute("height", Glib::ustring::format(height)); Glib::ustring scale = prefs->getString("/dialogs/import/scale"); @@ -254,11 +258,12 @@ Svg::open (Inkscape::Extension::Input *mod, const gchar *uri) } // convert filename to uri if (embed) { - std::unique_ptr pb(Inkscape::Pixbuf::create_from_file(uri)); + std::unique_ptr pb(Inkscape::Pixbuf::create_from_file(uri, svgdpi.c_str())); if(pb) { sp_embed_svg(image_node, uri); } - } else { + } + else { gchar* _uri = g_filename_to_uri(uri, nullptr, nullptr); if(_uri) { image_node->setAttribute("xlink:href", _uri); diff --git a/src/extension/system.cpp b/src/extension/system.cpp index 6802050b0c3f40ac82740b947ad8b13b57a359f4..2a74c6b0cc386de0b75846786f5f52c7cbedf67c 100644 --- a/src/extension/system.cpp +++ b/src/extension/system.cpp @@ -99,9 +99,10 @@ SPDocument *open(Extension *key, gchar const *filename) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool ask = prefs->getBool("/dialogs/import/ask"); Glib::ustring id = Glib::ustring(imod->get_id(), 22); - if (id.compare( "org.inkscape.input.svg") == 0 && - (strcmp(prefs->getString("/options/openmethod/value").c_str(), "import") != 0 || !ask)) - { + if (id.compare("org.inkscape.input.svg") == 0 && + ((strcmp(prefs->getString("/options/openmethod/value").c_str(), "done") != 0 && + strcmp(prefs->getString("/options/openmethod/value").c_str(), "import") != 0) || + !ask)) { show = false; imod->set_gui(false); } else if(strlen(imod->get_id()) > 27) { diff --git a/src/object/sp-image.cpp b/src/object/sp-image.cpp index a5bc115ce694b5cb81a6c06fa50f7e468abd964e..9c2fe9ac3e70b5e6b42de1e6cde245768374ac7a 100644 --- a/src/object/sp-image.cpp +++ b/src/object/sp-image.cpp @@ -72,7 +72,8 @@ static void sp_image_set_curve(SPImage *image); -static Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base ); +static Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base, + char const *svgdpi); static void sp_image_update_arenaitem (SPImage *img, Inkscape::DrawingImage *ai); static void sp_image_update_canvas_image (SPImage *image); @@ -117,7 +118,9 @@ SPImage::SPImage() : SPItem(), SPViewBox() { this->clipbox = Geom::Rect(); this->sx = this->sy = 1.0; this->ox = this->oy = 0.0; - + this->dpi = 96.00; + this->prev_width = 0.0; + this->prev_height = 0.0; this->curve = nullptr; this->href = nullptr; @@ -137,6 +140,7 @@ void SPImage::build(SPDocument *document, Inkscape::XML::Node *repr) { this->readAttr( "y" ); this->readAttr( "width" ); this->readAttr( "height" ); + this->readAttr("inkscape:svg-dpi"); this->readAttr( "preserveAspectRatio" ); this->readAttr( "color-profile" ); @@ -216,6 +220,10 @@ void SPImage::set(unsigned int key, const gchar* value) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_SVG_DPI: + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_IMAGE_HREF_MODIFIED_FLAG); + break; + case SP_ATTR_PRESERVEASPECTRATIO: set_preserveAspectRatio( value ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); @@ -330,11 +338,14 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) { this->pixbuf = nullptr; if (this->href) { Inkscape::Pixbuf *pixbuf = nullptr; - pixbuf = sp_image_repr_read_image ( - this->getRepr()->attribute("xlink:href"), - this->getRepr()->attribute("sodipodi:absref"), - doc->getBase()); - + const gchar *svgdpi = this->getRepr()->attribute("inkscape:svg-dpi"); + if (!svgdpi) { + svgdpi = "96"; + } + this->dpi = atof(svgdpi); + pixbuf = sp_image_repr_read_image(this->getRepr()->attribute("xlink:href"), + this->getRepr()->attribute("sodipodi:absref"), doc->getBase(), svgdpi); + if (pixbuf) { #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) if ( this->color_profile ) apply_profile( pixbuf ); @@ -348,7 +359,6 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) { // Why continue without a pixbuf? So we can display "Missing Image" png. // Eventually, we should properly support SVG image type (i.e. render it ourselves). - if (this->pixbuf) { if (!this->x._set) { this->x.unit = SVGLength::PX; @@ -398,8 +408,32 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) { this->sy = c2p[3]; } + + // TODO: eliminate ox, oy, sx, sy + sp_image_update_canvas_image ((SPImage *) this); + double proportion_pixbuf = this->pixbuf->height() / (double)this->pixbuf->width(); + double proportion_image = this->height.computed / (double)this->width.computed; + if (this->prev_width && + (this->prev_width != this->pixbuf->width() || this->prev_height != this->pixbuf->height())) { + if (std::abs(this->prev_width - this->pixbuf->width()) > std::abs(this->prev_height - this->pixbuf->height())) { + proportion_pixbuf = this->pixbuf->width() / (double)this->pixbuf->height(); + proportion_image = this->width.computed / (double)this->height.computed; + if (proportion_pixbuf != proportion_image) { + double new_height = this->height.computed * proportion_pixbuf; + sp_repr_set_svg_double(this->getRepr(), "width", new_height); + } + } + else { + if (proportion_pixbuf != proportion_image) { + double new_width = this->width.computed * proportion_pixbuf; + sp_repr_set_svg_double(this->getRepr(), "height", new_width); + } + } + } + this->prev_width = this->pixbuf->width(); + this->prev_height = this->pixbuf->height(); } void SPImage::modified(unsigned int flags) { @@ -437,7 +471,7 @@ Inkscape::XML::Node *SPImage::write(Inkscape::XML::Document *xml_doc, Inkscape:: if (this->height._set) { sp_repr_set_svg_double(repr, "height", this->height.computed); } - + repr->setAttribute("inkscape:svg-dpi", this->getRepr()->attribute("inkscape:svg-dpi")); //XML Tree being used directly here while it shouldn't be... repr->setAttribute("preserveAspectRatio", this->getRepr()->attribute("preserveAspectRatio")); #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) @@ -511,10 +545,12 @@ gchar* SPImage::description() const { this->document) { Inkscape::Pixbuf * pb = nullptr; - pb = sp_image_repr_read_image ( - this->getRepr()->attribute("xlink:href"), - this->getRepr()->attribute("sodipodi:absref"), - this->document->getBase()); + const gchar *svgdpi = this->getRepr()->attribute("inkscape:svg-dpi"); + if (!svgdpi) { + svgdpi = "96"; + } + pb = sp_image_repr_read_image(this->getRepr()->attribute("xlink:href"), + this->getRepr()->attribute("sodipodi:absref"), this->document->getBase(), svgdpi); if (pb) { ret = g_strdup_printf(_("%d × %d: %s"), @@ -537,7 +573,7 @@ Inkscape::DrawingItem* SPImage::show(Inkscape::Drawing &drawing, unsigned int /* return ai; } -Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base) +Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base, char const *svgdpi) { Inkscape::Pixbuf *inkpb = nullptr; @@ -547,7 +583,7 @@ Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absre if (strncmp (filename,"file:",5) == 0) { gchar *fullname = g_filename_from_uri(filename, nullptr, nullptr); if (fullname) { - inkpb = Inkscape::Pixbuf::create_from_file(fullname); + inkpb = Inkscape::Pixbuf::create_from_file(fullname, svgdpi); g_free(fullname); if (inkpb != nullptr) { return inkpb; @@ -556,7 +592,7 @@ Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absre } else if (strncmp (filename,"data:",5) == 0) { /* data URI - embedded image */ filename += 5; - inkpb = Inkscape::Pixbuf::create_from_data_uri(filename); + inkpb = Inkscape::Pixbuf::create_from_data_uri(filename, svgdpi); if (inkpb != nullptr) { return inkpb; } @@ -574,7 +610,7 @@ Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absre // different dir) or unset (when doc is not saved yet), so we check for base+href existence first, // and if it fails, we also try to use bare href regardless of its g_path_is_absolute if (g_file_test (fullname, G_FILE_TEST_EXISTS) && !g_file_test (fullname, G_FILE_TEST_IS_DIR)) { - inkpb = Inkscape::Pixbuf::create_from_file(fullname); + inkpb = Inkscape::Pixbuf::create_from_file(fullname, svgdpi); if (inkpb != nullptr) { g_free (fullname); return inkpb; @@ -585,7 +621,7 @@ Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absre /* try filename as absolute */ if (g_file_test (filename, G_FILE_TEST_EXISTS) && !g_file_test (filename, G_FILE_TEST_IS_DIR)) { - inkpb = Inkscape::Pixbuf::create_from_file(filename); + inkpb = Inkscape::Pixbuf::create_from_file(filename, svgdpi); if (inkpb != nullptr) { return inkpb; } @@ -603,7 +639,7 @@ Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absre g_warning ("xlink:href did not resolve to a valid image file, now trying sodipodi:absref=\"%s\"", absref); } - inkpb = Inkscape::Pixbuf::create_from_file(filename); + inkpb = Inkscape::Pixbuf::create_from_file(filename, svgdpi); if (inkpb != nullptr) { return inkpb; } @@ -633,7 +669,6 @@ sp_image_update_arenaitem (SPImage *image, Inkscape::DrawingImage *ai) static void sp_image_update_canvas_image(SPImage *image) { SPItem *item = SP_ITEM(image); - for (SPItemView *v = item->display; v != nullptr; v = v->next) { sp_image_update_arenaitem(image, dynamic_cast(v->arenaitem)); } diff --git a/src/object/sp-image.h b/src/object/sp-image.h index 464d0f144bdbaddbef3a194654d31bfe326f6d8f..7d62e756a813263dc26c57e767c0762c4badd270 100644 --- a/src/object/sp-image.h +++ b/src/object/sp-image.h @@ -35,6 +35,8 @@ public: Geom::Rect clipbox; double sx, sy; double ox, oy; + double dpi; + double prev_width, prev_height; SPCurve *curve; // This curve is at the image's boundary for snapping diff --git a/src/ui/dialog/object-attributes.cpp b/src/ui/dialog/object-attributes.cpp index ec3ce1b71645bdb9bac8174e1c6ac66eb2ee47ef..6801afa9c2e4aa98f30709abcabffd983e0acef2 100644 --- a/src/ui/dialog/object-attributes.cpp +++ b/src/ui/dialog/object-attributes.cpp @@ -67,7 +67,6 @@ static const SPAttrDesc image_desc[] = { { N_("Y:"), "y"}, { N_("Width:"), "width"}, { N_("Height:"), "height"}, - { N_("Image Rendering:"), "image-rendering"}, { nullptr, nullptr} }; diff --git a/src/ui/dialog/object-properties.cpp b/src/ui/dialog/object-properties.cpp index 8daa83e9c30dd0f4a48a77528d798584cc056afc..88d7daf074d10cc790e66457f13572f47f2f229e 100644 --- a/src/ui/dialog/object-properties.cpp +++ b/src/ui/dialog/object-properties.cpp @@ -48,14 +48,16 @@ namespace Dialog { ObjectProperties::ObjectProperties() : UI::Widget::Panel("/dialogs/object/", SP_VERB_DIALOG_ITEM) - , _blocked (false) + , _blocked(false) , _current_item(nullptr) , _label_id(_("_ID:"), true) , _label_label(_("_Label:"), true) , _label_title(_("_Title:"), true) + , _label_dpi(_("_DPI SVG:"), true) , _label_image_rendering(_("_Image Rendering:"), true) , _cb_hide(_("_Hide"), true) , _cb_lock(_("L_ock"), true) + , _cb_aspect_ratio(_("Pereserve Ratio"), true) , _attr_table(Gtk::manage(new SPAttributeTable())) , _desktop(nullptr) { @@ -185,12 +187,39 @@ void ObjectProperties::_init() _ft_description.add(_tv_description); _tv_description.add_mnemonic_label(*label_desc); + /* Create the text view box for the DPI svg */ + _ft_description.set_border_width(4); + _ft_description.set_sensitive(FALSE); + frame_desc->add(_ft_description); + _ft_description.set_shadow_type(Gtk::SHADOW_IN); + + _tv_description.set_wrap_mode(Gtk::WRAP_WORD); + _tv_description.get_buffer()->set_text(""); + _ft_description.add(_tv_description); + _tv_description.add_mnemonic_label(*label_desc); + + /* Create the label for the object title */ + _label_dpi.set_label(_label_dpi.get_label() + " "); + _label_dpi.set_halign(Gtk::ALIGN_END); + _label_dpi.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_label_dpi, 0, 3, 1, 1); + + /* Create the entry box for the SVG DPI */ + _spin_dpi.set_digits(2); + _spin_dpi.set_range(1, 1200); + grid_top->attach(_spin_dpi, 1, 3, 1, 1); + + _label_dpi.set_mnemonic_widget(_spin_dpi); + // pressing enter in the label field is the same as clicking Set: + _spin_dpi.signal_activate().connect(sigc::mem_fun(this, &ObjectProperties::_labelChanged)); + + /* Image rendering */ /* Create the label for the object ImageRendering */ _label_image_rendering.set_label(_label_image_rendering.get_label() + " "); _label_image_rendering.set_halign(Gtk::ALIGN_END); _label_image_rendering.set_valign(Gtk::ALIGN_CENTER); - grid_top->attach(_label_image_rendering, 0, 3, 1, 1); + grid_top->attach(_label_image_rendering, 0, 4, 1, 1); /* Create the combo box text for the 'image-rendering' property */ _combo_image_rendering.append( "auto" ); @@ -199,7 +228,7 @@ void ObjectProperties::_init() _combo_image_rendering.set_tooltip_text(_("The 'image-rendering' property can influence how a bitmap is up-scaled:\n\t'auto' no preference;\n\t'optimizeQuality' smooth;\n\t'optimizeSpeed' blocky.\nNote that this behaviour is not defined in the SVG 1.1 specification and not all browsers follow this interpretation.")); _combo_image_rendering.set_valign(Gtk::ALIGN_CENTER); - grid_top->attach(_combo_image_rendering, 1, 3, 1, 1); + grid_top->attach(_combo_image_rendering, 1, 4, 1, 1); _label_image_rendering.set_mnemonic_widget(_combo_image_rendering); @@ -207,6 +236,8 @@ void ObjectProperties::_init() sigc::mem_fun(this, &ObjectProperties::_imageRenderingChanged) ); + + /* Check boxes */ Gtk::HBox *hb_checkboxes = Gtk::manage(new Gtk::HBox()); contents->pack_start(*hb_checkboxes, FALSE, FALSE, 0); @@ -235,12 +266,20 @@ void ObjectProperties::_init() _cb_lock.signal_toggled().connect(sigc::mem_fun(this, &ObjectProperties::_sensitivityToggled)); + /* Preserve aspect ratio */ + _cb_aspect_ratio.set_tooltip_text(_("Check to preserve aspect ratio on images")); + _cb_aspect_ratio.set_hexpand(); + _cb_aspect_ratio.set_valign(Gtk::ALIGN_CENTER); + grid_cb->attach(_cb_aspect_ratio, 0, 1, 1, 1); + + _cb_aspect_ratio.signal_toggled().connect(sigc::mem_fun(this, &ObjectProperties::_aspectRatioToggled)); + /* Button for setting the object's id, label, title and description. */ Gtk::Button *btn_set = Gtk::manage(new Gtk::Button(_("_Set"), true)); btn_set->set_hexpand(); btn_set->set_valign(Gtk::ALIGN_CENTER); - grid_cb->attach(*btn_set, 2, 0, 1, 1); + grid_cb->attach(*btn_set, 1, 1, 1, 1); btn_set->signal_clicked().connect(sigc::mem_fun(this, &ObjectProperties::_labelChanged)); @@ -284,7 +323,7 @@ void ObjectProperties::update() return; } _blocked = true; - + _cb_aspect_ratio.set_active(item->getAttribute("preserveAspectRatio") == "true"); _cb_lock.set_active(item->isLocked()); /* Sensitive */ _cb_hide.set_active(item->isExplicitlyHidden()); /* Hidden */ @@ -409,6 +448,13 @@ void ObjectProperties::_labelChanged() _("Set object title")); } + /* Retrieve the DPI */ + if (SP_IS_IMAGE(obj)) { + Glib::ustring dpi_value = Glib::ustring::format(_spin_dpi.get_value()); + obj->setAttribute("inkscape:svg-dpi", dpi_value); + DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, _("Set image DPI")); + } + /* Retrieve the description */ Gtk::TextBuffer::iterator start, end; _tv_description.get_buffer()->get_bounds(start, end); @@ -464,6 +510,34 @@ void ObjectProperties::_sensitivityToggled() _blocked = false; } +void ObjectProperties::_aspectRatioToggled() +{ + if (_blocked) { + return; + } + + SPItem *item = SP_ACTIVE_DESKTOP->getSelection()->singleItem(); + g_return_if_fail(item != nullptr); + + _blocked = true; + + item->setLocked(_cb_aspect_ratio.get_active()); + const char *active; + if (_cb_aspect_ratio.get_active()) { + active = "true"; + } + else { + active = "none"; + } + /* Retrieve the DPI */ + if (SP_IS_IMAGE(item)) { + Glib::ustring dpi_value = Glib::ustring::format(_spin_dpi.get_value()); + item->setAttribute("preserveAspectRatio", active); + DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, _("Set preserve ratio")); + } + _blocked = false; +} + void ObjectProperties::_hiddenToggled() { if (_blocked) { diff --git a/src/ui/dialog/object-properties.h b/src/ui/dialog/object-properties.h index 4ce72ae1a1e27ad4460238cccd682d37dcc6ebb6..f603219c4eeaef661bd060f4f478870ef630ff87 100644 --- a/src/ui/dialog/object-properties.h +++ b/src/ui/dialog/object-properties.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -85,6 +86,7 @@ private: Gtk::Entry _entry_label; //the entry for the object label Gtk::Label _label_title; //the label for the object title Gtk::Entry _entry_title; //the entry for the object title + Gtk::Label _label_image_rendering; // the label for 'image-rendering' Gtk::ComboBoxText _combo_image_rendering; // the combo box text for 'image-rendering' @@ -93,7 +95,10 @@ private: Gtk::CheckButton _cb_hide; //the check button hide Gtk::CheckButton _cb_lock; //the check button lock + Gtk::CheckButton _cb_aspect_ratio; //the preserve aspect ratio of images + Gtk::Label _label_dpi; //the entry for the dpi value + Gtk::SpinButton _spin_dpi; //the expander for interactivity Gtk::Expander _exp_interactivity; //the expander for interactivity SPAttributeTable *_attr_table; //the widget for showing the on... names at the bottom @@ -118,6 +123,9 @@ private: /// Callback for checkbox Hide. void _hiddenToggled(); + /// Callback for checkbox Preserve Aspect Ratio. + void _aspectRatioToggled(); + /// Can be invoked for setting the desktop. Currently not used. void _setDesktop(SPDesktop *desktop); diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 5f9a402f11f80498e527170fb8947658668e6b26..b19b102217732a795e7490aeed5924d541e0d6ca 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -750,6 +750,8 @@ static void sp_recent_open(GtkRecentChooser *recent_menu, gpointer /*user_data*/) { // dealing with the bizarre filename convention in Inkscape for now + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString("/options/openmethod/value", "open"); gchar *uri = gtk_recent_chooser_get_current_uri(GTK_RECENT_CHOOSER(recent_menu)); gchar *local_fn = g_filename_from_uri(uri, nullptr, nullptr); gchar *utf8_fn = g_filename_to_utf8(local_fn, -1, nullptr, nullptr, nullptr); @@ -757,6 +759,7 @@ sp_recent_open(GtkRecentChooser *recent_menu, gpointer /*user_data*/) g_free(utf8_fn); g_free(local_fn); g_free(uri); + prefs->setString("/options/openmethod/value", "done"); } static void diff --git a/testfiles/src/attributes-test.cpp b/testfiles/src/attributes-test.cpp index e6fbe8eceb32977e40c8a4beac02ddb9bba20d84..34963f22d247271229cdc15a0d5142616c60cc6a 100644 --- a/testfiles/src/attributes-test.cpp +++ b/testfiles/src/attributes-test.cpp @@ -463,6 +463,7 @@ std::vector getKnownAttrs() AttributeInfo("inkscape:window-x", true), AttributeInfo("inkscape:window-y", true), AttributeInfo("inkscape:zoom", true), + AttributeInfo("inkscape:svg-dpi", true), AttributeInfo("osb:paint", true), AttributeInfo("sodipodi:arc-type", true), AttributeInfo("sodipodi:arg1", true),