diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2016-11-25 13:17:44 +0000 |
|---|---|---|
| committer | tavmjong-free <tavmjong@free.fr> | 2016-11-25 13:17:44 +0000 |
| commit | 07212a0ac053f34a7a695a82690196b5f38d80ab (patch) | |
| tree | f67420b68970f4523263143e7b47345f8551e295 /src | |
| parent | Remove deprecated GtkWidget-separator-height, ignored as of 3.20. (diff) | |
| download | inkscape-07212a0ac053f34a7a695a82690196b5f38d80ab.tar.gz inkscape-07212a0ac053f34a7a695a82690196b5f38d80ab.zip | |
Provide a way to update a legacy document to account for the 90 to 96 dpi change.
This method relies on setting the 'viewBox'.
(bzr r15273)
Diffstat (limited to 'src')
| -rw-r--r-- | src/display/canvas-grid.cpp | 34 | ||||
| -rw-r--r-- | src/display/canvas-grid.h | 10 | ||||
| -rw-r--r-- | src/file.cpp | 205 |
3 files changed, 228 insertions, 21 deletions
diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp index fa45fe02c..81d194b35 100644 --- a/src/display/canvas-grid.cpp +++ b/src/display/canvas-grid.cpp @@ -139,7 +139,7 @@ grid_canvasitem_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned }; CanvasGrid::CanvasGrid(SPNamedView * nv, Inkscape::XML::Node * in_repr, SPDocument *in_doc, GridType type) - : visible(true), gridtype(type) + : visible(true), gridtype(type), legacy(false), pixel(false) { repr = in_repr; doc = in_doc; @@ -528,6 +528,10 @@ CanvasXYGrid::readRepr() if( q.unit->type == UNIT_TYPE_LINEAR ) { // Legacy grid not in 'user units' origin[Geom::X] = q.value("px"); + legacy = true; + if (q.unit->abbr == "px" ) { + pixel = true; + } } else { // Grid in 'user units' origin[Geom::X] = q.quantity * scale_x; @@ -541,6 +545,10 @@ CanvasXYGrid::readRepr() if( q.unit->type == UNIT_TYPE_LINEAR ) { // Legacy grid not in 'user units' origin[Geom::Y] = q.value("px"); + legacy = true; + if (q.unit->abbr == "px" ) { + pixel = true; + } } else { // Grid in 'user units' origin[Geom::Y] = q.quantity * scale_y; @@ -559,6 +567,10 @@ CanvasXYGrid::readRepr() if( q.unit->type == UNIT_TYPE_LINEAR ) { // Legacy grid not in 'user units' spacing[Geom::X] = q.value("px"); + legacy = true; + if (q.unit->abbr == "px" ) { + pixel = true; + } } else { // Grid in 'user units' spacing[Geom::X] = q.quantity * scale_x; @@ -578,6 +590,10 @@ CanvasXYGrid::readRepr() if( q.unit->type == UNIT_TYPE_LINEAR ) { // Legacy grid not in 'user units' spacing[Geom::Y] = q.value("px"); + legacy = true; + if (q.unit->abbr == "px" ) { + pixel = true; + } } else { // Grid in 'user units' spacing[Geom::Y] = q.quantity * scale_y; @@ -798,7 +814,23 @@ CanvasXYGrid::updateWidgets() */ } +// For correcting old SVG Inkscape files +void +CanvasXYGrid::Scale (Geom::Scale const &scale ) { + origin *= scale; + spacing *= scale; + // Write out in 'user-units' + Inkscape::SVGOStringStream os_x, os_y, ss_x, ss_y; + os_x << origin[Geom::X]; + os_y << origin[Geom::Y]; + ss_x << spacing[Geom::X]; + ss_y << spacing[Geom::Y]; + repr->setAttribute("originx", os_x.str().c_str()); + repr->setAttribute("originy", os_y.str().c_str()); + repr->setAttribute("spacingx", ss_x.str().c_str()); + repr->setAttribute("spacingy", ss_y.str().c_str()); +} void CanvasXYGrid::Update (Geom::Affine const &affine, unsigned int /*flags*/) diff --git a/src/display/canvas-grid.h b/src/display/canvas-grid.h index 557bd6dab..bf520467a 100644 --- a/src/display/canvas-grid.h +++ b/src/display/canvas-grid.h @@ -101,6 +101,9 @@ public: static void on_repr_attr_changed (Inkscape::XML::Node * repr, const gchar *key, const gchar *oldval, const gchar *newval, bool is_interactive, void * data); + bool isLegacy() const { return legacy; } + bool isPixel() const { return pixel; } + bool isVisible() const { return (isEnabled() &&visible); }; bool isEnabled() const; @@ -118,7 +121,11 @@ protected: GridType gridtype; -private: + // For dealing with old Inkscape SVG files (pre 0.92) + bool legacy; + bool pixel; + + private: CanvasGrid(const CanvasGrid&); CanvasGrid& operator=(const CanvasGrid&); }; @@ -129,6 +136,7 @@ public: CanvasXYGrid(SPNamedView * nv, Inkscape::XML::Node * in_repr, SPDocument * in_doc); virtual ~CanvasXYGrid(); + virtual void Scale (Geom::Scale const &scale); virtual void Update (Geom::Affine const &affine, unsigned int flags); virtual void Render (SPCanvasBuf *buf); diff --git a/src/file.cpp b/src/file.cpp index d39d8c6ce..56d82d7bc 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -11,9 +11,10 @@ * Jon A. Cruz <jon@joncruz.org> * Abhishek Sharma * David Xiong + * Tavmjong Bah * * Copyright (C) 2006 Johan Engelen <johan@shouraizou.nl> - * Copyright (C) 1999-2012 Authors + * Copyright (C) 1999-2016 Authors * Copyright (C) 2004 David Turner * Copyright (C) 2001-2002 Ximian, Inc. * @@ -61,7 +62,12 @@ #include "event-log.h" #include "ui/dialog/font-substitution.h" -#include <gtkmm/main.h> +// For updating old Inkscape SVG files +#include "display/canvas-grid.h" +#include "sp-guide.h" + +#include <gtkmm.h> +//#include <gtkmm/main.h> #include <glibmm/miscutils.h> #include <glibmm/convert.h> @@ -130,15 +136,6 @@ SPDesktop *sp_file_new(const std::string &templ) DocumentUndo::setUndoSensitive(doc, true); } - // Set viewBox if it doesn't exist - if (!doc->getRoot()->viewBox_set - && (doc->getRoot()->width.unit != SVGLength::PERCENT) - && (doc->getRoot()->height.unit != SVGLength::PERCENT)) { - DocumentUndo::setUndoSensitive(doc, false); - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); - DocumentUndo::setUndoSensitive(doc, true); - } - SPDesktop *olddesktop = SP_ACTIVE_DESKTOP; if (olddesktop) olddesktop->setWaitingCursor(); @@ -279,14 +276,6 @@ bool sp_file_open(const Glib::ustring &uri, } if (doc) { - // Set viewBox if it doesn't exist - if (!doc->getRoot()->viewBox_set - && (doc->getRoot()->width.unit != SVGLength::PERCENT) - && (doc->getRoot()->height.unit != SVGLength::PERCENT)) { - DocumentUndo::setUndoSensitive(doc, false); - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); - DocumentUndo::setUndoSensitive(doc, true); - } SPDocument *existing = desktop ? desktop->getDocument() : NULL; @@ -313,6 +302,184 @@ bool sp_file_open(const Glib::ustring &uri, root->original.inkscape = root->version.inkscape; root->original.svg = root->version.svg; + if (INKSCAPE.use_gui()) { + + // See if we need to offer the user a fix for the 90->96 px per inch change. + // std::cout << "SPFileOpen:" << std::endl; + // std::cout << " Version: " << sp_version_to_string(root->version.inkscape) << std::endl; + + if ( sp_version_inside_range( root->version.inkscape, 0, 1, 0, 92 ) ) { + + // std::cout << " SVG file from old Inkscape version detected: " + // << sp_version_to_string(root->version.inkscape) << std::endl; + + + static const double ratio = 90.0/96.0; + + bool need_fix_viewbox = false; + bool need_fix_units = false; + bool need_fix_guides = false; + bool need_fix_grid_mm = false; + + // Check if potentially need viewbox or unit fix + switch (root->width.unit) { + case SP_CSS_UNIT_PC: + case SP_CSS_UNIT_MM: + case SP_CSS_UNIT_CM: + case SP_CSS_UNIT_IN: + need_fix_viewbox = true; + break; + case SP_CSS_UNIT_NONE: + case SP_CSS_UNIT_PX: + need_fix_units = true; + default: + break; + // OK + } + + switch (root->height.unit) { + case SP_CSS_UNIT_PC: + case SP_CSS_UNIT_MM: + case SP_CSS_UNIT_CM: + case SP_CSS_UNIT_IN: + need_fix_viewbox = true; + break; + case SP_CSS_UNIT_NONE: + case SP_CSS_UNIT_PX: + need_fix_units = true; + default: + break; + // OK + } + + // std::cout << "Absolute SVG units in root? " << (need_fix_viewbox?"true":"false") << std::endl; + // std::cout << "User units in root? " << (need_fix_units ?"true":"false") << std::endl; + + if (!root->viewBox_set && need_fix_viewbox) { + + std::string msg = _( + "Old Inkscape files used 1in == 90px. CSS requires 1in == 96px.\n" + "Drawing elements may be too small. This can be corrected by\n" + "setting the SVG 'viewBox' to compensate." ); + // "either setting the SVG 'viewBox' to compensate or by scaling\n" + // "all the elements in the drawing." + Gtk::Dialog scaleDialog( _("Old Inkscape file detected (90 DPI)"), false); + Gtk::Label info; + info.set_markup(msg.c_str()); + info.show(); + scaleDialog.get_content_area()->pack_start(info, false, false, 20); + scaleDialog.add_button("Set 'viewBox'", 1); + // scaleDialog.add_button("Scale elements", 2); + scaleDialog.add_button("Ignore", 3); + + gint response = scaleDialog.run(); + if (response == 1) { + doc->setViewBox(Geom::Rect::from_xywh( + 0, 0, + doc->getWidth().value("px") * ratio, + doc->getHeight().value("px") * ratio)); + } else if (response == 2 ) { + // Insert DPISwitcher code + } + need_fix_guides = true; // Always fix guides + } + + if (need_fix_units) { + std::string msg = ( + "Old Inkscape files used 1in == 90px. CSS requires 1in == 96px.\n" + "Drawings meant to match a physical size (e.g. Letter or A4)\n" + "will be too small. Scaling the drawing can correct for this.\n" ); + // "Internal scaling can be handled either by setting the SVG 'viewBox'\n" + // "attribute to compensate or by scaling all objects in the drawing." + Gtk::Dialog scaleDialog( _("Old Inkscape file detected (90 DPI)"), false); + Gtk::Label info; + info.set_markup(msg.c_str()); + info.show(); + scaleDialog.get_content_area()->pack_start(info, false, false, 20); + scaleDialog.add_button("Scale drawing", 1); + // scaleDialog.add_button("Set 'viewBox'", 1); + // scaleDialog.add_button("Scale elements", 2); + scaleDialog.add_button("Ignore", 3); + + gint response = scaleDialog.run(); + if (response == 1) { + + if (!root->viewBox_set) { + doc->setViewBox(Geom::Rect::from_xywh( + 0, 0, + doc->getWidth().value("px"), + doc->getHeight().value("px"))); + } + Inkscape::Util::Quantity width = + Inkscape::Util::Quantity(doc->getWidth().value("px")/ratio, "px" ); + Inkscape::Util::Quantity height = + Inkscape::Util::Quantity(doc->getHeight().value("px")/ratio,"px" ); + doc->setWidthAndHeight( width, height, false ); + + need_fix_guides = true; // Only fix guides if drawing scaled + } else if (response == 2) { + // Insert DPISwitcher code + } else { + // Ignore + need_fix_grid_mm = true; + } + } + + // Fix guides and grids + for (SPObject *child = root->firstChild() ; child; child = child->getNext() ) { + SPNamedView *nv = dynamic_cast<SPNamedView *>(child); + if (nv) { + if (need_fix_guides) { + // std::cout << "Fixing guides" << std::endl; + for (SPObject *child2 = nv->firstChild() ; child2; child2 = child2->getNext() ) { + SPGuide *gd = dynamic_cast<SPGuide *>(child2); + if (gd) { + gd->moveto( gd->getPoint() / ratio, true ); + } + } + } + + for(std::vector<Inkscape::CanvasGrid *>::const_iterator it=nv->grids.begin();it!=nv->grids.end();++it ) { + Inkscape::CanvasXYGrid *xy = dynamic_cast<Inkscape::CanvasXYGrid *>(*it); + if (xy) { + // std::cout << "A grid: " << xy->getSVGName() << std::endl; + // std::cout << " Origin: " << xy->origin + // << " Spacing: " << xy->spacing << std::endl; + // std::cout << (xy->isLegacy()?" Legacy":" Not Legacy") << std::endl; + Geom::Scale scale = doc->getDocumentScale(); + if (xy->isLegacy()) { + if (xy->isPixel()) { + if (need_fix_grid_mm) { + xy->Scale( Geom::Scale(1,1) ); // See note below + } else { + scale *= Geom::Scale(ratio,ratio); + xy->Scale( scale.inverse() ); /* *** */ + } + } else { + if (need_fix_grid_mm) { + xy->Scale( Geom::Scale(ratio,ratio) ); + } else { + xy->Scale( scale.inverse() ); /* *** */ + } + } + } else { + if (need_fix_guides) { + // HACK: Scaling the document does not seem to cause + // grids defined in document units to be updated. + // This forces an update. + xy->Scale( Geom::Scale(1,1) ); + } + } + } + } + } + } // Look for SPNamedView loop + + DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Update Document")); + + } // If old Inkscape version + } // If use_gui + // resize the window to match the document properties sp_namedview_window_from_document(desktop); sp_namedview_update_layers_from_document(desktop); |
