Ceci est une ancienne révision du document !
This month doesn’t just mark 15 years of Full Circle Magazine – I also celebrate a full decade of writing these Inkscape columns! Many thanks to everyone who has read any of them over the years, and I hope you’ve found them useful. One thing I’ve always tried to do is to explain the underlying reasons for some of the oddities and limitations in the way Inkscape operates, and this month is no different. Having described the operation of the Measure Segments LPE last time, in this instalment I’m going to look behind the curtain at how this effect differs quite radically from those that came before it. Please note, however, that this is just for information and education – you don’t actually need anything in this instalment to simply use the LPE in the way it was intended.
First, a quick reminder of how Live Path Effects worked historically. An LPE was applied to a single path, and produced a single path as its output. The output path would replace the source path in the image. Here’s a very simple example: the Roughen LPE, when applied to the two-node path on the left, produces the multi-node path on the right.
Looking at this in the XML editor, we can see that there’s still only a single path object, but as well as a multi-node “d” attribute, it also contains an “original-d” attribute (in the “inkscape” namespace”) which has only the two nodes of the original path.
This is a pretty clever way to implement LPEs. Inkscape understands the extra attributes in its own namespace, so is able to treat the effect as a live, editable feature, while other SVG renderers, such as web browsers, will still show the result of the LPE since it’s just a normal “d” attribute like you would find on any SVG path object.
This approach does, however, come with one big limitation. Because the output is just a single path, it can be given only one style. Even if that path appears to be multiple separate shapes, it’s actually just a single SVG path element, with gaps in the shape described by the “d” attribute (i.e. with sub-paths). If we look at the same two-node path with the “Ruler” path effect applied instead, you can see that the result gives the appearance of numerous small paths. While it would be nice to be able to style the ruler’s tick marks separately from the main spine of the shape, that simply isn’t possible because, despite appearances, the output is still just a single path, with a single style.
With the release of version 1.0, Inkscape has added the ability for path effects such as “Measure Segments” to break this historical limitation. No longer is an LPE limited to one path in, one path out. Let’s apply “Measure Segments” to the same two-node path:
Immediately we can see that there are multiple styles being applied here. Our original path maintains the thicker style we used when drawing it, but the lines added by the LPE are significantly thinner. How is this possible? Quite simply, the lines added by the LPE are no longer just sub-paths in a “d” attribute, but are additional SVG <path> and <text> elements in their own right. A quick look at the XML editor shows the difference. You might like to refer back to the earlier screenshot of this dialog, where the top section shows we just have a single layer with a single path in it. Now take a look at the document structure after applying this LPE:
In addition to our original path, we now have three extra <path> elements (two leader lines and one measurement line), plus a <text> element to hold the measured value. Because these are separate SVG elements, you can obviously select them individually in order to style each of them differently… can’t you? The answer to that question isn’t the straightforward yes or no you might expect, so let’s delve a little deeper still.
Intuitively, you might try to click on one of the new elements on the canvas in order to select it, but you’ll find that your clicks are in vain. Dragging a rubber band selection box doesn’t work either. The only thing you can select is the original path. Having selected that path, you can change its style as normal. As you’ve surmised by now, however, doing so will modify only the original path itself, not any of the elements added by the LPE. For example, note the difference in behaviour between the Ruler LPE and the Measure Segments LPE when I set a red stroke color on the original path.
As you’ll know from last month’s instalment, the color, font, line thickness, and other aspects of the Measure Segments LPE are set as part of the effect’s parameters, split between the “General” and “Options” tabs. Should we wish to make the dimensions match the color of the original path, for example, we’ll need to manually set it via the “Color and opacity” control in the “Options” tab. There’s no means of linking or inheriting styles, though, so if you subsequently change the stroke color of the original path, you’ll have to also remember to manually alter the LPE parameters to suit.
If we can’t select the new elements using the mouse on the canvas, is there another approach we could use? Selecting individual elements within the XML editor does still work, and selects the corresponding item on the canvas when you do so. Even with that selection made, mouse interactions are restricted: you can drag the resize handles, but still can’t drag the object itself to move it (though using the cursor keys will work); you also can’t click on the object in order to switch to the rotate/skew handles or other modes now available with the selection box. You can change the style though, as demonstrated by this image of a multi-colored dimension line, complete with gradients and a different font.
There’s just one problem with this approach, and it’s something of a deal-breaker. The “L” in LPE stands for “Live” because the output from an LPE is calculated dynamically whenever the original path changes, or the parameters are adjusted. This means that any manipulation of the original path – even just nudging the position of one of the nodes – or any changes to the LPE parameters, will cause the output to be recalculated and all your manual changes to be discarded. You might think that this is okay, so long as you do your changes last, and then don’t touch the object again, but the LPE output is also calculated when your file is loaded from disk: save the file, and reopen it later, and your manual changes are gone. There’s simply no way to manually edit the parts of the LPE such that Inkscape won’t throw your changes away at some point.
The reason that these new elements are not selectable on the canvas is that they’re all created in a “locked” state. The ability to lock objects has been in Inkscape for a long time, but has generally been a poor substitute for keeping objects arranged in suitable layers and locking the whole layer instead. This is because a locked object is difficult to unlock again – after all, you can’t select it with the mouse to indicate which object you want to unlock. This situation improved with the release of Inkscape 1.0, which added an “Unlock Objects Below” entry to the context menu (see part 101 of this series for more details). Perhaps we could use that to allow easier editing of the individual components of our dimension line?
Sure enough, right-clicking on the dimension, and selecting the Unlock option from the context menu, does make the individual elements selectable with the mouse. Now they can be individually styled, and can even be clicked on to switch to the rotate/skew handles and other selection box modes. Internally, what has happened is that the “sodipodi:insensitive” attribute has been removed from each element’s SVG node, which allows Inkscape to treat these elements like any normal selectable, movable, and editable objects… right until you edit the original path, alter the LPE parameters, or save and load the file. Unfortunately, just unlocking these objects isn’t enough to break their connection to the Live effect.
So what’s the solution? Is there a way that we can style the individual parts of the dimension lines beyond the limited options provided in the LPE parameters? Well, there is… but only in a way that removes their link to the original path. For example, do you want to style the leader lines as dashes, or with a different thickness to the arrowed dimension line? It’s possible, but only by also losing the live update of the text value when you move or modify the path.
The way to achieve this is to use the Path > Object to Path menu entry. Historically, this has been the mechanism used to “fix” the output of an LPE, collapsing all the “live” parts of the effect chain to produce just a plain and simple SVG path that has the same appearance as the final LPE output. With the Measure Segments LPE, you can still use this same menu entry to “fix” the LPEs output, except this time the command’s name becomes something of a misnomer: you are no longer converting the object into a <path> element, but rather breaking the link between the original path and the various generated <path> and <text> elements. In other words, choosing this option doesn’t actually convert your object into a path, but it does convert it into separate editable objects. Naturally, this means that the elements are no longer “live”, so you do lose all the auto-updating that is so useful in an effect like this.
For most people, all this talk of styling parts of the Measure Segments LPE will be somewhat academic. In the vast majority of cases, the normal output from the effect will be sufficient, and the parameters it provides will give enough flexibility to style the new elements well enough. If more complex adjustments are needed, then using Object to Path will usually suffice, even if it does mean sacrificing live updates of the dimensions. It would be great if Inkscape offered a means to indicate that an element has been manually styled, but that you still want the position and text content to update, but perhaps that’s too niche a requirement to warrant the development time.
Even if you don’t want to style the dimension parts, however, there’s one significant aspect of this LPE’s approach that you should be aware of, because the behaviour is quite surprising, and could easily catch you unawares. The behaviour of Measure Segments with regard to layers is, in my opinion, broken.
Let’s take another look at the new elements in the XML editor. This is the same content as the earlier screenshot, but I’ve cropped it to just show the relevant detail.
Notice that “path144” is indented compared with the rest of the elements? That’s the original path to which we’ve applied the LPE, and it’s indented because it is a child of the Inkscape layer (the <g> element above it). The newly created <path> and <text> elements, however, are not indented because they are siblings of the layer. This means that they live alongside the layer, not inside it, in the XML structure. Now let’s see what happens when we hide the layer.
The original line is hidden, but the dimension elements are not. They all live at the top level of the SVG, not within the same layer as the path they’re associated with, so aren’t affected by hiding the layer itself. This happens regardless of how deeply nested your original path is. Consider trying to create a technical drawing showing different views of an object: common sense would tell you to put each view in a separate layer so they can be turned on and off individually, but doing so will still leave the dimensions visible. In the following example the left hand image shows a simple technical drawing of a cylinder, while the right hand one shows the result of hiding the “Top View” layer. It’s not exactly what most people would expect.
There is a solution to this issue, but it’s not pretty. You can unlock the generated dimension content (right-click > Unlock Objects Below) – though you may need to do this multiple times for each part of the content. Then you need to select all the parts. Finally you can move them into the right layer using the Layer > Move Selection to Layer… menu option. Doing this will cause Inkscape to re-run the LPE, locking the objects again, but they will now be on the correct layer. The good news is that, once they’ve been moved, they tend to stay put. Further changes to the path or the LPE parameters won’t suddenly break them back out to the top level again. It would be much better, though, if Inkscape simply created them in the same layer as the original path by default.
Last month we looked at how to use this effect in practical terms. This time we’ve examined some of the technical details behind it. Now that the genie is out of the bottle, it’s likely that future LPEs will also create new elements rather than just single paths, so understanding what’s happening, and how they’re different from older LPEs, might be a useful skill to add to your Inkscape repertoire.