In order to release 0.91, I tried to fix the most pressing issues with units. (and committed the work to trunk for testing)
On 25-11-2014 12:46, Tavmjong Bah wrote:
Hi,
It has been hard to keep track of everything going on with units in the past couple of days. I've got some comments about what has been done and where we should be headed. Please add your comments.
'display_units'
I think we all agree that inkscape:document-units is meant to be
'display_units'. Johan's changing of 'doc_units' to 'display_units' should make this much clearer. Thanks Johan!
(BTW, I change 'units' to 'page_size_units' last week for similar reasons.)
'svg_units'
...
But one could also have a valid file with:
<svg width="20mm" height="20mm" viewBox="0 0 40 40" ...>
where the 'user unit' is equivalent to 0.5mm.
This is what 'svg-units' is supposed to mean. "0.5 mm". Currently, this is not supported. If the scale factor cannot be found in the unit table, a special "user unit" should be added to the unit table / updated with the "0.5 mm" factor. That then becomes the "svg_units". Similarly in inkey.py where we also try to derive the "svg units" from width&viewbox.
We really should support arbitrary scaling (including non-isotropic). So instead of an 'svg unit' we should have an 'svg scale'. (Our rendering already supports arbitrary scaling so it would be a shame if our GUI didn't too, see the example SVG below.)
My focus is to release 0.91, where I think we should just skip this aspect of SVG's capabilities.
- % values on root 'width' and 'height'
I saw something on IRC about % values on the root SVG 'width' and 'height'. This is actually a very common use case for web designers where the SVG is to automatically fill a space. Inkscape treats % values on the 'width' and 'height' by using the values from the 'viewBox' (or if there is no 'viewBox' it assumes all values are in pixels). Here is an example of where 'width' and 'height' are in % and the scaling is non-isotropic. Inkscape renders it just fine:
I chose to ignore the possibility of percentages. So units will probably not work very well with such (awkward) documents. I believe it is correct to do something random in such cases anyway. As you write, the percentages mean to fill the space available. This space can be anything, so any arbitrary scaling can be applied to X and Y and no-one can tell you you are wrong. :) So Inkscape now probably does something random with units, and it is all standard compliant ;-)
- Precision
The SVG spec says that values like length are floats and this is indeed what we use internally in Inkscape. I am wondering if we should change this to double as it would make internal calculations more precise. This might avoid some of the rounding errors when switching units back and forth from say 'mm' to 'pc'.
Indeed, I was surprised at this when fixing a unit-test bug. +1 for simply changing the internals to type double.
We allow the user to set the numerical precision to up to 16 digits. This makes little sense given that floats are good to only 6 or 7.
- Converting between 90/96 dpi
I think our focus here is to do the minimum possible to convert an SVG file between 90 and 96 dpi. Trying to scale everything inside the file is rarely going to work satisfactory for a file of any complexity. Here are some things we should try (I am brain storming here):
a. Add a 'viewBox'
If a file has been created to a specific size using only user units, say A4 at 90dpi, using on user-units then one can set the SVG root to be:
<svg width="210mm" height="297mm" viewBox="0 0 744.09448819 1052.3622047" ...>
I think in 0.91.1, we should automatically add a viewbox when none is present (using 90 dpi). I believe this will solve many potential forward compatibility issues. If in trunk we then implement the "0.5 mm" user unit thing (see above), opening 0.91 document in 0.92 should pretty much work (I think?).
b. Absolute sizes are really only important for producing printed matter. We could add a 'dpi' factor. Values must be converted in PDF/PostScript export from 90 or 96dpi to 72dpi. The conversion factor could be user selectable. (Although adding a 'viewBox' as above should take care of this.)
Absolute page size, perhaps. But being able to specify the dimensions of an object in units that are not going to change depending on the viewer is very useful too. As you say, viewbox takes care of this. No extra stuff needed. When there is no viewbox present, we can automatically add one but first ask the user what DPI he wants to use (could be arbitrary value really).
c. Grids and guides and ?
These currently are defined in external units (no consideration of transforms, viewBox, etc.). Guides should be easy to auto adjust using the SVG scale (as defined above). Grids may be too (but I haven't tried yet).
Note: We will need to update grids and guides when we do the coordinate flip so if we do need a more sophisticated solution we can do it at the same time.
There is a branch (not ready for merging) that fixes up grids and guides to use proper SVG units like the rest of the SVG document.
d. Use internally of 'unit identifiers'.
If absolute unit identifiers ('mm', 'in', 'pt', etc.) have been used internally (other than on the root SVG element), then these do need to be scaled to account for a switch between 90dpi and 96dpi. This is not a problem for pre-0.91 Inkscape created files. To keep it from being a problem in 0.91 Inkscape files, we need to disable saving 'font-size' with a 'pt' unit identifier.
So then please disable that!
-Johan