On Wed, 2014-12-03 at 13:04 -0800, Bryce Harrington wrote:
On Wed, Dec 03, 2014 at 02:40:07PM +0100, Tavmjong Bah wrote:
Hi,
I have been living, breathing, and even dreaming units the past couple of weeks.
:-D
Thanks so much for staying focused on this. And thanks for setting up a wiki page for it.
My understanding of what Inkscape does and what it should do has evolved over the time period but now I think it has pretty much solidified. I thank all those that have given feedback.
I've tried to put all this knowledge at one place:
wiki.inkscape.org/wiki/index.php/Units_In_Inkscape
Conclusions:
- There are only three attributes that matter:
The SVG root 'width'
The SVG root 'height'
The 'viewBox'
Together they define a mapping of the real world to 'user units', in
particular they define a scaling factor.
Probably should define 'user units' here, and maybe even give examples of what you mean by 'real world units'.
I've updated the Wiki page to respond to most of you comments.
Introducing an additional attribute 'svgUnit' is probably unwise.
The document class should have a member function that returns the scale based on the above attributes. Note: the SVG spec allows non-uniform scaling and an offset which Inkscape handles without problem so a Geom::Affine should really be returned.
The svgUnit mention is kind of non-sequitor here... I've not been following developments on units so it may be common knowledge but for future reference it might help to say where the svgUnit (proposal? change?) comes from and was intended to do.
Johan proposed adding the 'svgUnit' which would be Inkscape's best guess at what the real world value of the 'user unit'. So if the width attribute has a value of 100mm and the 'viewBox' says the document is 100 'user units' wide, the svgUnit would be a 'mm'. I feel this is not necessary and in fact less than optimal as it doesn't handle cases where the 'user unit' is different in x and y (which is allowed in SVG and which is handled perfectly fine by Inkscape).
- The user should be offered the possibility of changing these
attributes in a simple way that makes sense to a non-expert:
Change page size:
The 'width' and/or 'height' are changed to the new page size with
the 'viewBox' changing to keep the same scaling factor. This is what Inkscape does now and has in the past.
So this is literally just switching from e.g. 8.5x11 to 8.5x14 paper size, and your drawing remains unchanged, just the page gets longer?
Exactly, just as Inkscape already does (with the exception it sometimes adds an unnecessary transform to account for the fact that Inkscape's y coordinate is upside down).
Change page scale:
The 'viewBox' is changed to set the a new scale factor (the page
remains the same size). The GUI should offer the ability to pick a suitable scale factor (e.g. 1 mm == 1 'user unit') from a drop-down menu as well as allow the knowledgeable user to pick a custom scale by setting the 'viewBox' directly (via an expandable section that is normally hidden, like the as is done with the margin settings). Changing the scale factor will result in already existing objects (shapes, paths, text) changing size relative to the page. (Trying to keep the relative sizes constant is difficult and error prone except in the one possible case of wrapping all the content in a group and applying an inverse transform to the group.)
With these transforms in mind, it is easy to see what should be done
with the 90 dpi to 96 dpi transition. The main problem is for drawings of a specific size like A4 where the width and height are defined in pixels using 90 dpi. To 'fix' these files, change the width and height to use 'mm' or 'in' and then add an appropriate 'viewBox' to set the scale of the 'user unit' to 90 dpi.
Gotcha. So with page scale, the units are literally the physical dimensions of the printed out page. And if I understand right, it would be very rare for a user to need to tinker with these settings?
Only if the user wants to change to a different size paper.
There's one more that fits nicely here:
Change dimensioning scale:
Drawings of real world physical things (e.g. a map or technical
drawing) are created in terms of real world physical units (meters, miles, nanometers, etc.) The dimensioning scale allows for representing a 10 foot pole by a thin but proportionately correct rectangle on an 8.5x11" page. By keeping everything properly scaled, an engineer could use a ruler to measure elements from the page, multiply the measurement by the dimensioning scale, and know what the corresponding real world physical length should be.
The dimensioning scale is defined in terms of 'user units',
(e.g. '5 km == 1 user unit'). Combining this with the page scale, we communicate to the user a 'page dimensioning scale' (e.g. '5 km to 1 mm'). The GUI should present a widget for selecting or entering the 'page dimensioning scale'. If the selected dimensioning scale replaces a previously specified dimensioning scale (i.e. it wasn't set to 1:1), then the drawing elements are scaled accordingly. (E.g. you start up Inkscape and draw a town map without considering the scale, then set it after the fact changing it from 1":1" to 1 mile per inch; no scaling takes place. Later you're asked to include the outskirts of town, so you set the scale factor to 2 miles per inch, and your existing drawn streets and buildings shrunk by half.)
When it's set, the dimensioning scale can control the units shown in
the GUI, the position and spacing of the grid and guides, and the formatting of labels in the document (such as printed measurements, dimensioning arrows, etc.)
That seems like a reasonable extension. BTW, we already support the non-standard 'm' and 'ft' unit identifiers in the GUI (the page size is actually written out as 'cm' and 'in' respectively).
Guides/Grids/3D Box Tool
Guides, grids and the 3D box tool coordinates should be stored as
'user units'. This can be seen by the simple exercise of asking what one would expect to happen under the above transformations:
Consider drawing a rectangle, duplicate it and then covert the
duplicate to guides. As the page is resized and rescaled one expects the guides to stick to the rectangle's edges.
Trunk already has code to define guides in terms of 'user units'.
This code should be back-ported to 0.91. It should be relatively easy to handle the 3D box tool coordinates the same way. Grids are a bit more problematic because they allow (actually require) the use of unit identifiers (which are not allowed for guides and 3d box tool coordinates). If the unit identifier is not 'px' then there will be a problem between 0.91 (90dpi) and trunk (96dpi). We can offer an extension to make this conversion for grids and 3D box tool coordinates.
Sounds like some unit unit test writing should be high on the todo list for 0.92. Do we have any test cases yet for guides and grids?
There is a page of test cases. The link is at the end of the above mentioned page. I need to add some test for the 3D box tool.
Tav