My first inkscape task after Friday:
If a "ghost spike" is detected (i.e. if the curve goes too far from the data points) then use a sharp corner instead of a smooth node.
I wouldn't expect this to have much effect on the cases being discussed here.
After that, there are a couple of possible freehand changes, and also three non-freehand patches, which I'll discuss first because they're more ready, and in the hope of comments as to what stuff's worth doing when.
- A simple patch adding a g_return_val_if_fail to something in sp-object.cpp. There are two possible conditions: one equivalent to what would cause a crash now anyway, or a tighter but simpler (and less random-looking) test. I'd like to check callers to see whether I can use the simpler tighter test. And get mental's opinion too.
- A patch whose correctness one can be fairly confident of but whose benefits are relatively minor:
- Rejecting some strings that have a valid value as a prefix, e.g. rejecting foo=nonebglx rather than treating it as foo=none.
- Minor efficiency gain through using memcmp instead of strcmp (though a reviewer may prefer to keep strcmp for simpler-looking code).
- A patch that makes our style string parsing more conformant, both in what we accept and what we reject. The patch more or less rewrites sp_style_merge_from_style_string, so is harder to verify correctness. We could just fix where we currently reject style strings that have lots of whitespace (caused by confusion as to whether trim_space sets *right to a length or final index) and delay applying the rewrite until after 0.40, so that it gets more testing.
Back to freehand:
- I have a fairly short patch that affects only the first segment of the curve (so it's helpful for short / smooth curves but no significant effect for the signature example). Its effect will improve fairly straight lines, but worsen curves that start with a sharp bend: more specifically, curves whose initial radius of curvature is comparable to or smaller than the tolerance.
Actually, you can tell what its effect will be by looking at the current CVS version of inkscape and comparing the start of the curve with the end of the curve (which already has this modification).
See below for comments on tolerance setting.
- I have a larger, unfinished, patch that delays committing a curve until we have two (or more) curves' worth of data points. This patch would approximately triple the CPU cost of freehand drawing, in exchange for a small improvement in curve fidelity.
That improvement can be built on if we use more sophisticated maths for curve estimation (for yet more CPU cost, as well as of course development effort).
On the subject of the default tolerance setting:
I really think the ideal tolerance would be a function of pointer speed. (I'm not commenting on how worthwhile it would be to implement this.) The thinking is that if one is moving fast then clearly[*1] one is not paying much attention to the exact position of the pointer, so we can use a larger tolerance and get smooth curves (assuming smoothness is considered good). If moving slowly, then it may be that one cares about the position, or maybe the user's just resting the pointing device, so we shouldn't make the tolerance too small, but at least it needn't make allowance for the broad-strokes case.
[*1]: Exception: if using a tablet and tracing around a physical object (e.g. the templates used by architects when using pencil on paper, or tracing something with a distinctive shape, for use as line art).
Some experimentation would be needed as to the right function, and we'd want, say, two parameters instead of the current one. That should be enough to adjust for different people's thinking speed (which may differ markedly if on medication, and I'd guess in other cases too, though I wouldn't know).
pjrm.