Difference between revisions of "Units In Inkscape"

From Inkscape Wiki
Jump to navigation Jump to search
 
(22 intermediate revisions by 3 users not shown)
Line 5: Line 5:
=Historical View=
=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 there 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).
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=
=The Philosophy=


Absolute units should not be used inside an SVG file with one exception:
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
The ''root'' width and height may have units, which with a proper
Line 15: Line 15:
"real" world value of the SVG ''user unit''.) This reflect the opinion of
"real" world value of the SVG ''user unit''.) This reflect the opinion of
the majority of the SVG working group.
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
It should be noted that the relative units ''em'', ''ex'', and ''%'' can be
Line 21: Line 23:
=Definitions=
=Definitions=


To better understand the following discussion it is necessary to have well defined terms to describe which ''unit'' is being talked about:
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
; User Unit
: A term defined by the SVG specification: [http://www.w3.org/TR/SVG/coords.html#Units a value in the current user coordinate system].
: A term defined by the SVG specification: [http://www.w3.org/TR/SVG/coords.html#Units 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 '[http://www.w3.org/TR/css3-values/#absolute-lengths' absolute]' unit identifiers: 'mm', 'cm', 'in', 'pt', 'pc', 'px' and several '[http://www.w3.org/TR/css3-values/#relative-lengths 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 ==


; External Unit Identifier
; GUI Unit Identifier ('inkscape:document-units')
: The unit identifier in the root SVG ''width'' or ''height'' attribute. If the ''width'' is '10in', the External Unit Identifier is 'in'.
: 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.


; External Unit
;Page Size Unit Identifier (namedview 'units')
: A length of 1 as expressed with the External Unit Identifier. If the ''width'' is '10in', the External Unit is '1in'.
: 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.


; Internal Unit
: The basic SVG unit. Never uses 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 from the root SVG ''width''/''height'' attributes and the ''viewBox''.


; GUI Unit Identifier
== Example ==
: 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).


;inkscape:document-units
Consider an SVG with the following SVG root element:
: Actually a Unit Identifier. Need to review code to see what it really means.


;units (inside namedview)
<pre>
: Actually a Unit Identifier. Need to review code to see what it really means.
<svg width="10in" height="6in" viewBox="0 0 50 30">
</pre>
 
; 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 &amp; Units=
=Inkscape &amp; 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 lenghts with unit identifiers from non-Inkscape produced files according to the  CSS defined value of 96 pixels (initial user-units) per inch.[http://www.w3.org/TR/css3-values/#absolute-lengths]
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.[http://www.w3.org/TR/css3-values/#absolute-lengths]


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 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''
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''.
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''.


For example:
For example:
Line 64: Line 93:
one "mm".
one "mm".


The Inkscape property ''inkscape:document-units'' should be set to "mm".
The ''SVG scale factor'' would be 1mm/1 user-unit.


Question: Why do we have this property? Can't it be determined from ''width'' and/or ''height''?
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'.


Answer:
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.
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.
A 2013 GSoC project by Matthew Petroff unified the Units handling in Inkscape, mostly implementing this philosophy. Inconsistencies should be viewed as bugs.


= Use Scenarios =
= Page Size and Drawing Scale Changes =


How does/should Inkscape behave in various use scenarios?
How does/should Inkscape behave in various use scenarios?


== Cases ==
== 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 ===


* Pixel art <p>Should not be a problem. Everything is done in user units.</p>
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.
* A4/Letter size page. <p>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.</p>
* Scaled drawings. <p>Scaling determined by document size and viewBox. The current implementation does not handle arbitrary scaling well.</p>


== Document Unit Changes ==


* Resize page
; Guides
*# Grids/guides should not change.
: 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.
*# 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)


; 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.


Notes:
; Perspective (3D boxes)
: Needs same treatment as guides. Code is already in trunk. It needs to be back-ported to 0.91.


# Guides are currently defined in external units, no unit identifier is allowed.
; Other
# Grids are current defined in external units, a unit identifier is required.
: ?


=Notes=
== Test Files ==


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.
See [http://tavmjong.free.fr/INKSCAPE/UNITS/ Test Files]

Latest revision as of 16:54, 22 December 2019

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.
  1. 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.
  2. The width of '10in' could be equivalently written as '25.4cm', '254mm', etc.
  3. 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).
  1. 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).
  2. 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'.
  3. 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