I have now implemented pages sizes using real world units as well as document units using a viewBox as described in my previous post. Although it is mostly working, there are a few known bugs when changing the document unit, namely connectors and 3d boxes do not scale properly. I have also worked on fixing regressions introduced by the phase one unit refactor.
Besides document-wide units, it is also useful to have object specific units for convenience. As real world units are handled as scaling factors of the document unit by the SVG specification, they are only recommended for the document size, not individual objects, and their values are counterintuitive when a viewBox is used to specify document-wide units. Therefore, I’ve decided to implement object specific units using an inkscape:unit attribute instead, which will also allow for units not defined in the SVG specification, e.g. feet. The manner in which object sizes and positions are written to a SVG file will not change; the attribute will only be used to remember which unit should be displayed when an object is selected in the Inkscape UI. Continue reading →
Since my last update, my branch for phase one of my Google Summer of Code project, unit refactoring, has been merged into the Inkscape trunk. I have now created a new branch for phase two, improvement of unit support. In order to improve unit support, one must first start with how units are defined in the SVG specification. In SVG, there are two types of coordinates, those defined in user space and those defined in real world units. If no unit is specified, it is assumed to be in user space units. By defining the document size in real world units and applying an equivalent viewBox attribute, one can define the user space unit to be a real world unit, e.g. millimeters.
< ?xml version="1.0" standalone="no"?>
< !DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
<svg width="74mm" height="52mm" version="1.1"
viewBox="0 0 74 52" xmlns="http://www.w3.org/2000/svg">
<!-- The dimensions for this rectange are given in user space, but
due to the viewBox attribute having the same values as the
document size specified in millimeters, the user units are
<rect x="10" y="5" width="30" height="20"></rect>
As the width and height of the document are 74mm and 52mm respectively and the viewBox stretches the user space width from 0 to 74 and the user space height from 0 to 52, the user space unit is equivalent to millimeters. Continue reading →
When I began working on phase one of my Google Summer of Code project, Inkscape’s unit handling code was scattered between multiple implementations with different files using different, incompatible implementations. I since consolidated this code into one implementation, residing in util/units.*, eliminating SPUnit, SPMetric, and unit-constants.h.
I also started to replace the SVGLength class but then changed my mind about doing so as the class is specific to the SVG specification, not general units. For example, common units, e.g. feet, are not part of the specification. I still may make it a child class of Util::Unit during phase two, depending on how I end up implementing things, but will leave it alone for now.
With these changes, I have consolidated Inkscape’s unit handling code, completing phase one of my Google Summer of Code project. Although there are only some minor user-facing changes, mostly bug fixes, the internal changes will facilitate the addition of user-facing changes both in phase two and beyond. As an example, pixels per inch are no longer hard-coded, so I plan on adding an option both in Inkscape preferences and document properties to configure the relationship between pixels and physical units early on in phase two. To begin phase two, I plan on hand-crafting SVG files with various types of unit configurations and then implementing support for them starting with a default document-wide unit.
As I have never used GTK+/gtkmm before, I spent a few days reading documentation to familiarize myself with the library, after getting stuck on transitioning parts of the UI to Inkscape::Util::Unit. With a better understanding of how the UI worked, I was able to make good progress and have completely eliminated SPUnit and SPMetric from the code base.
This leaves one significant section of unit code to port, SVGLength, which I hope to finish by the end of the week, as well as a couple other minor sections of code. I’m a few weeks behind schedule but hope to finish the refactor before the end of the month.
Based on suggestions on inkscape-devel, I took a look at Boost Units. At first it looked promising, but then I decided it’s more trouble than it’s worth as it’s aimed at compile time dimensional analysis, and Inkscape only deals with distance anyway. However, I did use Boost Units’ naming scheme of calling a measurement with its unit a “quantity” instead of a “length,” as Inkscape also uses angles, not just lengths.
In addition, I began porting the code base away from helper/units.cpp. In the process, I fixed a bug that appears to have been there for years; the CSE paper size didn’t have units displayed next to it in the page size selector dialog. There were if statements checking if each paper size unit was millimeters, inches, or pixels and adding the units on. As CSE paper is Inkscape’s only paper size defined in points, its units weren’t displayed as there wasn’t a specific check for points. Now the page size selector just displays the unit’s abbreviation, no individual checks required.