Units In Inkscape
This page documents the philosophy for Units handling inside Inkscape. Units are not as straight-forward as one should think they are.
Part of the problem with units in SVG and CSS in general is why they are there in the first place. In the early days it was assumed that one would want to display drawings on a screen at full scale. In otherwords, a "one inch square" would be displayed on a screen as a physical one inch square. This required that displays be queryable as to what their true DPI was. Display manufactures rarely provided the means to query the DPI of the display, and when they did, they often returned incorrect results. Thus, the use of "real" units never became popular and in reality it is usually not what one wanted. Eventually, after long arguments, the CSS working group dictated that one inch would be fixed to 96 pixels regardless of screen resolution (ironically, with so called Retina displays, there is once again interest in scaling drawings based on DPI).
Absolute units should not be used inside an SVG file with one exception:
The root width and height may have units, which with a proper viewBox determines an appropriate scale for a drawing. (This sets the "real" world value of the SVG user unit.) This reflect the opinion of the majority of the SVG working group.
It should be noted that the relative units em, ex, and % can be useful in some cases.
To better understand the following discussion it is necessary to have well defined terms to describe which unit is being talked about. Often unit is used when one should use unit identifier.
- User Unit
- A term defined by the SVG specification: a value in the current user coordinate system.
- External Unit Identifier
- The unit identifier in the root SVG width or height attribute. If the width is '10in', the External Unit Identifier is 'in'.
- External Unit
- A length of 1 as expressed with the External Unit Identifier. If the width is '10in', the External Unit is '1in'.
- Internal Unit
- The basic SVG unit. Never used with a unit identifier. It is the initial value of the User Unit. The real world value of the Internal Unit is determined by the scale determined from the root SVG width/height attributes and the viewBox.
- GUI Unit Identifier
- The unit identifier displayed in the GUI. It is generally not used when storing numerical values inside the SVG file (e.g. a width may be displayed in in but stored as a user unit).
- Actually a Unit Identifier. Read in as SPNamedView->doc_units. Need to review code to see what it really means.
Directly read in sp-namedview.cpp, read and written in ui/dialog/document-properties.cpp, metafile-inout.cpp, test_reassemble.c. SPNamedView::getDefaultUnit() returns 'pt', ugh!
- units (inside namedview)
- Actually a Unit Identifier. Read in as SPNamedView->units.
Only used in ui/widget/page-sizer.cpp. It's only use is to set the default unit in the page-sizer widget but this is rather useless as selecting a different page size will override it (and inkscape:document-units will be used if it is missing).
Inkscape & Units
Inkscape should not write out lengths with unit identifiers ('in', 'mm', etc.) other than in the root SVG element. Inkscape must, however, be able to interpret lengths with unit identifiers from non-Inkscape produced files according to the CSS defined value of 96 pixels (initial user-units) per inch.
The use of unit identifiers in the Inkscape GUI is for ease of authoring only. The actual values should be stored as user-units.
Changing the Inkscape Document unit should not introduce any transforms on elements nor should changing the SVG root width/height or the viewBox.
The GUI should show sizes taking into account both the Inkscape Document unit identifier(?) as well as the choosen GUI unit identifier, taking into account the width/height and viewBox.
<svg width="100mm" height="100mm" viewBox="0 0 100 100">
describes a drawing 100mm x 100mm where one user-unit is equivalent to one "mm".
The Inkscape property inkscape:document-units should be set to "mm".
Question: Why do we have this property? Can't it be determined from width and/or height?
Answer: It should be determined from the viewBox and width/height. We need to be able to handle files where the ratio is not one of the SVG units.
If the GUI unit identifier is set to "mm" then the GUI would show a width of '25.4' for a rectangle 25.4 user-units wide. If the GUI unit identifier is set to "in", the GUI would show '1.0'.
A 2013 GSoC project by Matthew Petroff unified the Units handling in Inkscape, mostly implementing this philosophy. Inconsistencies should be viewed as bugs.
How does/should Inkscape behave in various use scenarios?
- Pixel art
Should not be a problem. Everything is done in user units.
- A4/Letter size page.
Here the key is exporting to PDF. PDF follows postscript and uses 72 units per inch. Documents sized in terms of pixels need to be scaled properly (0.91 72/90, 0.92 72/96). This could be handled by an export option like is done for PNG export. Documents sized in terms of real units should not have a problem.
- Scaled drawings.
Scaling determined by document size and viewBox. The current implementation does not handle arbitrary scaling well.
Document Unit Changes
- Resize page
- Grids/guides should not change.
- It might be useful to able to specify a guide at 50%.
- Rescale page
- Change width/height but leave viewBox alone
- Change viewBox but leave width/height alone
- Change document units
- Very messy and bug prone.
- Edit a 90dpi unit in 0.92 (96dpi)
- Edit a 96dpi unit in 0.91 (90dpi)
- Guides are currently defined in external units, no unit identifier is allowed.
- Grids are current defined in external units, a unit identifier is required.
The outer SVG width/height, viewBox, and document-units should not be changed in the XML Editor. Use the Page tab of the Document Properties to change the document size or document unit to avoid the risk of them becoming inconsistent.