summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--share/extensions/docinfo.inx21
-rw-r--r--share/extensions/dpi90to96.inx23
-rw-r--r--share/extensions/dpi96to90.inx23
-rw-r--r--share/extensions/dpiswitcher.py219
-rw-r--r--src/file.cpp72
5 files changed, 339 insertions, 19 deletions
diff --git a/share/extensions/docinfo.inx b/share/extensions/docinfo.inx
new file mode 100644
index 000000000..c3d76a960
--- /dev/null
+++ b/share/extensions/docinfo.inx
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
+ <_name>DOC Info</_name>
+ <id>org.inkscape.docinfo</id>
+ <dependency type="executable" location="extensions">dpiswitcher.py</dependency>
+ <dependency type="executable" location="extensions">inkex.py</dependency>
+ <param name="action" type="notebook" gui-hidden="true">
+ <page name="page_info" _gui-text="Show page info">
+ <_param name="d" type="description">Choose this tab if you would like to see page info previously to apply DPI Switcher.</_param>
+ </page>
+ </param>
+ <effect needs-live-preview="false">
+ <object-type>all</object-type>
+ <effects-menu>
+ <submenu _name="Document"/>
+ </effects-menu>
+ </effect>
+ <script>
+ <command reldir="extensions" interpreter="python">dpiswitcher.py</command>
+ </script>
+</inkscape-extension>
diff --git a/share/extensions/dpi90to96.inx b/share/extensions/dpi90to96.inx
new file mode 100644
index 000000000..e7ad4a895
--- /dev/null
+++ b/share/extensions/dpi90to96.inx
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
+ <_name>DPI 90 to 96</_name>
+ <id>org.inkscape.dpi90to96</id>
+ <dependency type="executable" location="extensions">dpiswitcher.py</dependency>
+ <dependency type="executable" location="extensions">inkex.py</dependency>
+ <param name="action" type="notebook" gui-hidden="true">
+ <page name="dpi_swicher" >
+ <param name="switcher" type="enum" gui-hidden="true">
+ <item value="0">DPI Switch from 90 to 96</item>
+ </param>
+ </page>
+ </param>
+ <effect needs-live-preview="false">
+ <object-type>all</object-type>
+ <effects-menu>
+ <submenu _name="Document"/>
+ </effects-menu>
+ </effect>
+ <script>
+ <command reldir="extensions" interpreter="python">dpiswitcher.py</command>
+ </script>
+</inkscape-extension>
diff --git a/share/extensions/dpi96to90.inx b/share/extensions/dpi96to90.inx
new file mode 100644
index 000000000..11d1cb40b
--- /dev/null
+++ b/share/extensions/dpi96to90.inx
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
+ <_name>DPI 96 to 90</_name>
+ <id>org.inkscape.dpi96to90</id>
+ <dependency type="executable" location="extensions">dpiswitcher.py</dependency>
+ <dependency type="executable" location="extensions">inkex.py</dependency>
+ <param name="action" type="notebook" gui-hidden="true">
+ <page name="dpi_swicher" >
+ <param name="switcher" type="enum" gui-hidden="true">
+ <item value="1">DPI Switch from 96 to 90</item>
+ </param>
+ </page>
+ </param>
+ <effect needs-live-preview="false">
+ <object-type>all</object-type>
+ <effects-menu>
+ <submenu _name="Document"/>
+ </effects-menu>
+ </effect>
+ <script>
+ <command reldir="extensions" interpreter="python">dpiswitcher.py</command>
+ </script>
+</inkscape-extension>
diff --git a/share/extensions/dpiswitcher.py b/share/extensions/dpiswitcher.py
new file mode 100644
index 000000000..e7adbc0cf
--- /dev/null
+++ b/share/extensions/dpiswitcher.py
@@ -0,0 +1,219 @@
+#!/usr/bin/env python
+'''
+This extension scale or reduce a document to fit diferent SVG DPI -90/96-
+
+Copyright (C) 2012 Jabiertxo Arraiza, jabier.arraiza@marker.es
+
+Version 0.5 - DPI Switcher
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+'''
+
+import inkex, sys, re, string
+from lxml import etree
+
+class DPISwitcher(inkex.Effect):
+
+ def __init__(self):
+ inkex.Effect.__init__(self)
+ self.OptionParser.add_option("--switcher", action="store",
+ type="string", dest="switcher", default="0",
+ help="Select the DPI switch you want")
+ self.OptionParser.add_option("--action", action="store",
+ type="string", dest="action",
+ default=None, help="")
+ self.factor_a = 90.0/96.0
+ self.factor_b = 96.0/90.0
+ self.units = "px"
+ self.unitExponent = 1.0
+
+ def scaleRoot(self, svg):
+ widthNumber = re.sub("[a-zA-Z]", "", svg.get('width'))
+ heightNumber = re.sub("[a-zA-Z]", "", svg.get('height'))
+ widthDoc = str(float(widthNumber) * self.factor_a * self.unitExponent)
+ heightDoc = str(float(heightNumber) * self.factor_a * self.unitExponent)
+ if svg.get('viewBox'):
+ widthNumber = svg.get('viewBox').split(" ")[2]
+ heightNumber = svg.get('viewBox').split(" ")[3]
+ if svg.get('height'):
+ svg.set('height', heightDoc)
+ if svg.get('width'):
+ svg.set('width', widthDoc)
+ if svg.get('viewBox'):
+ svg.set('viewBox',"0 0 " + str(float(widthNumber) * self.factor_a) + " " + str(float(heightNumber) * self.factor_a))
+ if self.options.switcher == "1":
+ self.scaleGuides(svg)
+ self.scaleGrid(svg)
+ for element in svg:
+ box3DSide = element.get(inkex.addNS('box3dsidetype', 'inkscape'))
+ if box3DSide:
+ continue
+ uri, tag = element.tag.split("}")
+ width_scale = self.factor_a
+ height_scale = self.factor_a
+ if tag == "rect" or tag == "image" or tag == "path" or tag == "circle" or tag == "ellipse" or tag == "text":
+ if element.get('width') is not None and \
+ (re.sub("[0-9]*\.?[0-9]", "", element.get('width')) == "%" or \
+ re.sub("[0-9]*\.?[0-9]", "", element.get('width')) == "px"):
+ width_scale = 1.0;
+ if element.get('height') is not None and \
+ (re.sub("[0-9]*\.?[0-9]", "", element.get('height')) == "%" or \
+ re.sub("[0-9]*\.?[0-9]", "", element.get('height')) == "px"):
+ height_scale = 1.0;
+ if element.get('x') is not None and \
+ re.sub("[0-9]*\.?[0-9]", "", element.get('x')) == "%":
+ xpos = str(float(element.get('x').replace('%','')) * self.factor_b) + '%'
+ element.set('x', xpos)
+ if element.get('y') is not None and \
+ re.sub("[0-9]*\.?[0-9]", "", element.get('y')) == "%":
+ ypos = str(float(element.get('y').replace('%','')) * self.factor_b) + '%'
+ element.set('y', ypos)
+ if element.get('transform'):
+ if "matrix" in str(element.get('transform')) and width_scale != 1.0:
+ result = re.sub(r".*?matrix( \(|\()(.*?)\)", self.matrixElement, str(element.get('transform')))
+ element.set('transform', result)
+ if "scale" in str(element.get('transform')) and width_scale != 1.0:
+ result = re.sub(r".*?scale( \(|\()(.*?)\)", self.scaleElement, str(element.get('transform')))
+ element.set('transform', result)
+ if "translate" in str(element.get('transform')) and width_scale != 1.0:
+ result = re.sub(r".*?translate( \(|\()(.*?)\)", self.translateElement, str(element.get('transform')))
+ element.set('transform', result)
+ if "skew" in str(element.get('transform')) and width_scale != 1.0:
+ result = re.sub(r".*?skew( \(|\()(.*?)\)", self.skewElement, str(element.get('transform')))
+ element.set('transform', result)
+ if "scale" not in str(element.get('transform')) and "matrix" not in str(element.get('transform')):
+ element.set('transform', str(element.get('transform')) + "scale(" + str( width_scale) + ", " + str(height_scale) + ")")
+ else:
+ element.set('transform', "scale(" + str(width_scale) + ", " + str(height_scale) + ")")
+
+ #a dictionary of unit to user unit conversion factors
+ __uuconv = {'in':96.0, 'pt':1.33333333333, 'px':1.0, 'mm':3.77952755913, 'cm':37.7952755913,
+ 'm':3779.52755913, 'km':3779527.55913, 'pc':16.0, 'yd':3456.0 , 'ft':1152.0}
+
+ __uuconvLegazy = {'in':90.0, 'pt':1.25, 'px':1, 'mm':3.5433070866, 'cm':35.433070866, 'm':3543.3070866,
+ 'km':3543307.0866, 'pc':15.0, 'yd':3240 , 'ft':1080}
+
+ def scaleElement(self, m):
+ scaleVal = m.group(2).replace(" ","")
+ total = scaleVal.count(',')
+ if total == 1:
+ scaleVal = scaleVal.split(",")
+ return "matrix(" + str(float(scaleVal[0]) * self.factor_a) + ",0,0," + str(float(scaleVal[1]) * self.factor_a) + ",0,0)"
+ else:
+ return "matrix(" + str(float(scaleVal) * self.factor_a) + ",0,0," + str(float(scaleVal) * self.factor_a) + ",0,0)"
+
+
+ def translateElement(self, m):
+ translateVal = m.group(2).replace(" ","")
+ total = translateVal.count(',')
+ if total == 1:
+ translateVal = translateVal.split(",")
+ return "matrix(" + str(self.factor_a) + ",0,0," + str(self.factor_a) + "," + str(float(translateVal[0]) * self.factor_a) + "," + str(float(translateVal[1]) * self.factor_a) + ")"
+ else:
+ return "matrix(" + str(self.factor_a) + ",0,0," + str(self.factor_a) + "," + str(float(translateVal) * self.factor_a) + "," + str(float(translateVal) * self.factor_a) + ")"
+
+ def skewElement(self, m):
+ skeweVal = m.group(2).replace(" ","")
+ total = skewVal.count(',')
+ if total == 1:
+ skeweVal = skewVal.split(",")
+ return "skew(" + str(float(skewVal[0]) * self.factor_a) + "," + str(float(skewVal[1]) * self.factor_a) + ") matrix(" + str(self.factor_a) + ",0,0," + str(self.factor_a) + ",0,0)"
+ else:
+ return "skew(" + str(float(skewVal) * self.factor_a) + ") matrix(" + str(self.factor_a) + ",0,0," + str(self.factor_a) + ",0,0)"
+
+ def matrixElement(self, m):
+ matrixVal = m.group(2).replace(" ","")
+ total = matrixVal.count(',')
+ matrixVal = matrixVal.split(",")
+ if total == 5:
+ return "matrix(" + str(float(matrixVal[0]) * self.factor_a) + "," + matrixVal[1] + "," + matrixVal[2] + "," + str(float(matrixVal[3]) * self.factor_a) + "," + str(float(matrixVal[4]) * self.factor_a) + "," + str(float(matrixVal[5]) * self.factor_a) + ")"
+
+ def scaleGuides(self, svg):
+ xpathStr = '//sodipodi:guide'
+ guides = svg.xpath(xpathStr, namespaces=inkex.NSS)
+ for guide in guides:
+ point = string.split(guide.get("position"), ",")
+ guide.set("position", str(float(point[0].strip()) * self.factor_a ) + "," + str(float(point[1].strip()) * self.factor_a ))
+
+ def scaleGrid(self, svg):
+ xpathStr = '//inkscape:grid'
+ grids = svg.xpath(xpathStr, namespaces=inkex.NSS)
+ for grid in grids:
+ grid.set("units", "px")
+ if grid.get("spacingx"):
+ spacingx = str(float(re.sub("[a-zA-Z]", "", grid.get("spacingx"))) * self.factor_a) + "px"
+ grid.set("spacingx", str(spacingx))
+ if grid.get("spacingy"):
+ spacingy = str(float(re.sub("[a-zA-Z]", "", grid.get("spacingy"))) * self.factor_a) + "px"
+ grid.set("spacingy", str(spacingy))
+ if grid.get("originx"):
+ originx = str(float(re.sub("[a-zA-Z]", "", grid.get("originx"))) * self.factor_a) + "px"
+ grid.set("originx", str(originx))
+ if grid.get("originy"):
+ originy = str(float(re.sub("[a-zA-Z]", "", grid.get("originy"))) * self.factor_a) + "px"
+ grid.set("originy", str(originy))
+
+ def effect(self):
+ action = self.options.action.strip("\"") # TODO Is this a bug? (Extra " characters)
+ saveout = sys.stdout
+ sys.stdout = sys.stderr
+ svg = self.document.getroot()
+ if action == "page_info":
+ print ":::SVG document related info:::"
+ print "version: " + str(svg.get(inkex.addNS('version',u'inkscape')))
+ width = svg.get('width')
+ if width:
+ print "width: " + width
+ height = svg.get('height')
+ if height:
+ print "height: " + height
+ viewBox = svg.get('viewBox')
+ if viewBox:
+ print "viewBox: " + viewBox
+ namedview = svg.find(inkex.addNS('namedview', 'sodipodi'))
+ docunits= namedview.get(inkex.addNS('document-units', 'inkscape'))
+ if docunits:
+ print "document-units: " + docunits
+ units = namedview.get('units')
+ if units:
+ print "units: " + units
+ xpathStr = '//sodipodi:guide'
+ guides = svg.xpath(xpathStr, namespaces=inkex.NSS)
+ xpathStr = '//inkscape:grid'
+ if guides:
+ numberGuides = len(guides)
+ print "Document has " + str(numberGuides) + " guides"
+ grids = svg.xpath(xpathStr, namespaces=inkex.NSS)
+ i = 1
+ for grid in grids:
+ print "Grid number " + str(i) + ": Units: " + grid.get("units")
+ i = i+1
+ else:
+ if self.options.switcher == "0":
+ self.factor_a = 96.0/90.0
+ self.factor_b = 90.0/96.0
+ namedview = svg.find(inkex.addNS('namedview', 'sodipodi'))
+ namedview.set(inkex.addNS('document-units', 'inkscape'), "px")
+ self.units = re.sub("[0-9]*\.?[0-9]", "", svg.get('width'))
+ if self.units and self.units <> "px" and self.units <> "" and self.units <> "%":
+ if self.options.switcher == "0":
+ self.unitExponent = 1.0/(self.factor_a/self.__uuconv[self.units])
+ else:
+ self.unitExponent = 1.0/(self.factor_a/self.__uuconvLegazy[self.units])
+ self.scaleRoot(svg);
+ sys.stdout = saveout
+
+effect = DPISwitcher()
+effect.affect()
diff --git a/src/file.cpp b/src/file.cpp
index ee66cc162..38c07311d 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -34,6 +34,7 @@
#include "ui/dialog/ocaldialogs.h"
#include "desktop.h"
+#include "extension/effect.h"
#include "document-private.h"
#include "document-undo.h"
#include "ui/tools/tool-base.h"
@@ -312,14 +313,13 @@ bool sp_file_open(const Glib::ustring &uri,
// 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;
+ bool is_extension = false;
// Check if potentially need viewbox or unit fix
switch (root->width.unit) {
@@ -358,20 +358,18 @@ bool sp_file_open(const Glib::ustring &uri,
if (!root->viewBox_set && need_fix_viewbox) {
std::string msg = _(
- "Old Inkscape files used 1in == 90px. CSS requires 1in == 96px.\n"
+ "Old Inkscape files use 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."
+ "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("Scale elements", 2);
scaleDialog.add_button("Ignore", 3);
-
gint response = scaleDialog.run();
if (response == 1) {
doc->setViewBox(Geom::Rect::from_xywh(
@@ -379,27 +377,42 @@ bool sp_file_open(const Glib::ustring &uri,
doc->getWidth().value("px") * ratio,
doc->getHeight().value("px") * ratio));
} else if (response == 2 ) {
- // Insert DPISwitcher code
+ std::list<Inkscape::Extension::Effect *> effects;
+ Inkscape::Extension::db.get_effect_list(effects);
+ std::list<Inkscape::Extension::Effect *>::iterator it = effects.begin();
+ bool did = false;
+ while (it != effects.end()) {
+ if (strcmp((*it)->get_id(), "org.inkscape.dpi90to96") == 0) {
+ Inkscape::UI::View::View *view = desktop;
+ (*it)->effect(view);
+ did = true;
+ break;
+ }
+ ++it;
+ }
+ if (!did) {
+ std::cerr << "sp_file_open: Failed to find dpi90to96 extension." << std::endl;
+ }
+ is_extension = true;
}
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"
+ "Old Inkscape files use 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."
+ "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);
+ scaleDialog.add_button("Set 'viewBox'", 1);
+ scaleDialog.add_button("Scale elements", 2);
+ scaleDialog.add_button("Ignore", 3);
gint response = scaleDialog.run();
if (response == 1) {
@@ -418,7 +431,24 @@ bool sp_file_open(const Glib::ustring &uri,
need_fix_guides = true; // Only fix guides if drawing scaled
} else if (response == 2) {
- // Insert DPISwitcher code
+ std::list<Inkscape::Extension::Effect *> effects;
+ Inkscape::Extension::db.get_effect_list(effects);
+ std::list<Inkscape::Extension::Effect *>::iterator it = effects.begin();
+ bool did = false;
+ while (it != effects.end()){
+ if (strcmp((*it)->get_id(), "org.inkscape.dpi90to96") == 0) {
+ Inkscape::UI::View::View *view = desktop;
+ (*it)->effect(view);
+ did = true;
+ break;
+ }
+ ++it;
+ }
+ if (!did) {
+ std::cerr << "sp_file_open: Failed to find dpi90to96 extension." << std::endl;
+ }
+ need_fix_guides = true; // Only fix guides if drawing scaled
+ is_extension = true;
} else {
// Ignore
need_fix_grid_mm = true;
@@ -467,7 +497,11 @@ bool sp_file_open(const Glib::ustring &uri,
// 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) );
+ if(is_extension){
+ xy->Scale( Geom::Scale(ratio,ratio).inverse() );
+ } else {
+ xy->Scale( Geom::Scale(1,1) );
+ }
}
}
}