Units In Inkscape
Introduction
This page documents the philosophy for Units handling inside Inkscape. Units are not as straight-forward as one should think they are.
Historical View
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).
The Philosophy
Absolute units (other than 'px' inside CSS) 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.
In CSS a unit identifier must be present. As 'px' is defined in SVG to be the same as a user unit the following are equal: font-size="20" and style="font-size:20px".
It should be noted that the relative units em, ex, and % can be useful in some cases.
Definitions
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.
Generic SVG
- User Unit
- A term defined by the SVG specification: a unit length in the current user coordinate system.
- Unit Identifier
- The part of a length value that expresses the units used to interpret the length. In SVG there are six 'absolute' unit identifiers: 'mm', 'cm', 'in', 'pt', 'pc', 'px' and several 'relative' unit identifiers: 'em', 'ex', '%', ...
- SVG Scale Factor
- A scale factor determined by SVG root 'width'/'height' and the 'viewBox'. It serves to map 'user units' inside an SVG document to the real world.
Inkscape specific
- GUI Unit Identifier ('inkscape:document-units')
- The unit identifier displayed in the GUI.
- It should not be used when storing numerical values inside the SVG file (e.g. a width may be displayed in mm in the GUI but should be stored in 'user units').
- During the run-up to 0.91 it was used in some places to represent the "SVG Scale".
- Read in as SPNamedView->doc_units. This value is returned in 0.91 by getDefaultUnit() and in trunk by getDisplayUnit(). (Renamed to avoid confusion.)
- Read in sp-namedview.cpp, read and written in ui/dialog/document-properties.cpp, metafile-inout.cpp, test_reassemble.c.
- Page Size Unit Identifier (namedview 'units')
- The unit identifier displayed in the page size widget.
- It's only use is to set the default unit in the page-sizer widget. The variable has been renamed to 'page_size_units' in trunk.
- Read in as SPNamedView->units. Only used in ui/widget/page-sizer.cpp.
Example
Consider an SVG with the following SVG root element:
<svg width="10in" height="6in" viewBox="0 0 50 30">
- Drawing size
- This is a nominal 10x6 inch drawing.
- The actual size of the drawing when displayed depends on how it is displayed. It is very unlikely to be the nominal size when displayed on a digital screen.
- The width of '10in' could be equivalently written as '25.4cm', '254mm', etc.
- The width could also be written as '960' or '960px' using the CSS/SVG defined value of 96 pixels per inch.
- If a 'unit identifier' is missing or 'px', the length is interpreted to be in 'user units'. CSS requires the use of a 'unit identifier'. Thus while one can write 'font-size="20"' (an SVG presentation attribute), one must write 'style="font-size:20px" (a CSS style value).
- Inkscape 0.91 and earlier used a value of 90 pixels per inch.
- Initial 'user unit'
- The 'viewBox' defines the drawing to be 50 'user units' wide and 30 'user units' high (with no offset of the origin).
- A rectangle with 'width="10"' is 10 'user units' wide which would correspond to 2 inches at the nominal drawing size (if no scaling transforms are applied).
- A rectangle with 'width="1in"' is 96 'user-units' wide, corresponding to a width of 19.2 inches at the nominal drawing size. This is not what one would naively expect and is the reason the use of 'unit identifiers' is not recommended inside the SVG document (other than on the root 'width' and 'height'.
- The 'user unit' can be scaled by a transform. For example, if a group has a scaling transform of 0.5 ('transform="scale(0.5,0.5)'), the 'user unit' is half the length of the initial 'user unit' and objects inside the group are drawn at half their nominal size.
- SVG scale factor
- The scale factor is 0.2 inches per initial 'user unit'. (10 inches/50 'user units). SVG allows for different scale factors in 'x' and 'y'.
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.[1]
The use of unit identifiers in the Inkscape GUI is for ease of authoring only. The actual values should be stored as user-units.
The GUI should show values taking into account the GUI display unit identifier as well as the SVG scale calculated from the width/height and viewBox.
For example:
<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 SVG scale factor would be 1mm/1 user-unit.
If the GUI display unit ('inkscape:document-units') 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 display unit identifier is set to "in", the GUI would show '1.0'.
Note: In the run-up to 0.91 the Inkscape Document unit was sometimes used incorrectly as the SVG scale factor resulting in a number of bugs.
A 2013 GSoC project by Matthew Petroff unified the Units handling in Inkscape, mostly implementing this philosophy. Inconsistencies should be viewed as bugs.
Page Size and Drawing Scale Changes
How does/should Inkscape behave in various use scenarios?
Use Cases
- Pixel art
- Every thing is done with 'user units'. No page size/scale to worry about.
- A4/Letter/etc. size page
- The page size is defined by the SVG 'width'/'height' attributes. Pre-0.91 the scale is 'user unit' == 1px with the assumption of 90dpi. To correct for 96dpi, set the 'width' and 'height' attributes using 'mm' or 'in' and add a 'viewBox' calculated at 90dpi. In 0.91, one can set the 'viewBox' to define the 'user unit' to be 1px, 1mm, 1in, etc.
- Scaled drawings
- Scaling determined by document size and viewBox.
Page Size/Scale Changes
- Page size is determined by SVG root 'width' and 'height'.
- 'viewBox' defined in 'user units' with the values: (x offset, y-offset, width, height).
- Document scale is determined by ratio of 'width'/'height' to 'viewBox'.
Operations
- Change page size
- Change 'width'/'height' in GUI, 'viewBox' changed to keep scale. Grids/guides do not need any change.
- Change document scale
- Change via a 'Scaling' section in GUI which changes the 'viewBox'. Include a preset with common values ('mm', 'in', etc. to 1 'user unit') and a (normally hidden) custom 'viewBox' entry box.
Editing Aides
Guides, grids, and other editing aides should be defined in terms of 'user units'. These will then behave as a user would expect when the document size or scale is changed. To see how this behavior should work, draw a rectangle, duplicate it, and then use the duplicate to create a set of guides. As the document size or scale is changed, the guides should follow along the edges of the rectangle.
- Guides
- Pre 0.91 guides are defined in 'external units' which are the same as 'user units' (no 'viewBox'). No 'unit identifier' is permitted so there is no problem with the 90dpi to 96dpi conversion. Code is already in trunk to define guides in terms of 'user units'. It needs to be back-ported to 0.91, otherwise guides in documents where the scale is not unity will be shifted in trunk.
- Grids
- Pre 0.91 grids are defined in 'external units'. A 'unit identifier' is permitted (in fact, required) thus there will be a problem if real units were used (e.g. 'cm') to define the grid with the 90dpi to 96dpi conversion. No code has been added to trunk yet to handle this case. Unit identifiers should not be used but have been available at least since 0.48.
- Perspective (3D boxes)
- Needs same treatment as guides. Code is already in trunk. It needs to be back-ported to 0.91.
- Other
- ?
Test Files
See Test Files