Hi.
I'm Juan Luis Boya. As a Semester of Code project (http://semesterofcode.com/)
I've have been for some time trying to add alternative stroke
alignment options to Inkscape.
There is an in-progress W3C draft for SVG2 that attempts to
introduce a property named `stroke-alignment` for this purpose. This
is an attempt to create an implementation of it. http://www.w3.org/TR/svg-strokes/
This property would control the placement of path strokes. This is
better explained with an example. See this image: http://i.imgur.com/GIqKrwj.png
The image shows the same rectangle with four different stroking
modes. The black line represents the shape path, as that you would
see with the 'Edit paths by nodes' tool in Inkscape. Shown in orange
is the stroke of the path as would be seen by the user.
A issue with the previous proposal was there was no definition for
open paths. I propose to amend this in two ways:
a) Adding two new values: `left` and `right`. `left` would place the
stroke at the left of each path segment. The direction of the path
is determined by the order of the nodes, in the same manner arrow
lines work. The following image shows an example of how this would
work: http://i.imgur.com/otULloP.png
b) `inset` and `outset` would work as if the shapes were closed with
a straight line, except that line would not be rendered.
The property would be set as an style property (in CSS code). Add a
few toggle buttons would be added to the Inkscape UI in the Stroke
Style tab in order to control the value of the property.
As for the implementation:
1. The offsetting would be done only to the stroke line, which will
still be rendered as an stroked line (instead of being converted to
a polygon).
2. The property would be added to NRStyle and SPStyle classes.
3. Add buttons to the Stroke Style UI.
4. As far as I know, paths are rendered in
DrawingShape::_renderItem(). This method reads style properties from
a class member named _nrstyle. (Therefore we need to add properties
to both NRStyle and SPStyle).
Now, this method would read the property and stroke appropriately.
At the time of writing Cairo does not have support for a style
property like this, so we will do the offsetting in Inkscape.
a) If the value is center, the same path would be used for both
stroke and fill.
b) In other case, first fill will be applied using the original
path, then the offsetted path would be calculated and stroked.
For the stroke-alignment values 'right' and 'left' applying the
offset is as simple as offsetting by stroke-width/2, positive or
negative respectively.
'inset' and 'outset' are a bit more problematic, especially for
self-intersecting shapes. This figure shows how a self-intersecting
pentagram would approximately look with different values of
stroke-alignment if 'inset' and 'outset' are considered valid for
self-intersecting paths. http://i.imgur.com/s8sLumk.png
In this document I explain a procedure to stroke them, but there are
some required algorithms I don't know, remarked in "Issue" boxes:
https://inkscape.org/en/gallery/item/6356/stroke-alignment.pdf
As for the state of the implementation:
* After quite a bit of time I've got to understand the classes that
make Inkscape render shapes. I have been able to add the required
SVG property to Inkscape. I'll commit it soon. The controls in the
UI will be hidden under a compile time flag.
* I've written code to outline the stroke, but also...
* I've found several important bugs in half_outline() that cause it
to fail even for simple shapes. For instance, this is the result of
passing a triangle to half_outline() when it has been drawn
counterclockwise: http://i.imgur.com/3Tq9SvZ.jpg For that specific
bug I have a provisional fix, but it should be examined more
closely.
Regards,
Juan Luis.