Variation fonts

Thanks for the info @GeorgSeifert. I understand that “dead” curves (zero length handle) is not the most correct way to draw, but as TimAhrens said, I’m using it as a technique to reach such stress on the letter shapes.

Thanks @TimAhrens for the tip. I’m trying to use it, but it is not working. I have the filter on all of my instances:

What am I doing wrong? (ps: i’m using the trial version)

You cannot apply these parameters on a Variable Font. Just select all glyphs and run the filter directly.

1 Like

I was working on a proper handle normalisation method bit didn’t finish it and then I got busy with something else. I’ll have a look.

There’s no need to “extract” the handles for a TrueType conversion. A cubic Bezier with one control point is mathematically valid. You just have to know, when you (Georg) are calculating the start and end angle of the curve segment, as you probably do when you convert to TrueType, you have to use the one visible control point for both angles. The retracted point needs to be ignored.

As long as common rasterizers choke on these curves, it may be advisable to avoid them, even if they are not a bug. I don’t know if the macOS rasterizer bug has ever been reported or fixed.

Technically, there isn’t but if Georg’s current algorithm gives bad results with retacted BCPs then practically, it is necessary to first extract them.

A cubic Bezier with one control point is … impossible. If it has one BCP then it is a quadratic curve. And, unfortunately, a cubic curve with a retracted BCP does not have the same shape as the corresponding quadratic one (with the retracted BCP “deleted”).

It is certainly advisable to avoid them in the final, distributed fonts, to account for possible bugs in rasterizers. What I don’t like is that retracted BCPs are protrayed as bad practice when designing, i.e. drawing glyphs.

It is hard to convert when the curve is shallow, like only a few units deep. There is no real advantage to retracting BCPs (not over the same segment with ~67% and ~49% BCP length); arguably they are disadvantageous, because they create an uneven distribution in the curve (compared to the same segment with both BCPs at ~59% length). And since they are easy enough to avoid from the start, of course, I will advise against using them.

It is not only TT conversion, offsetting and Apple device rendering. There are also problems with a range of printer drivers. And a PostScript rasterizer (or emulation) can exceed allocated printer memory when it creates too many subpaths, which can happen easily when you have many small half-dead curves. I had a case where running FixZeroHandles made a font work on a PS printer that previously would generate the Too Many Subpaths error. Also, in interpolation, rounding errors can cause the BCP to bypass the on-curve. Shouldn’t happen, I know, but it is a risk.

This is the J from JAF Bernini Serif Light Banner, which I was working on this week.

The selected curve is 1 unit deep (I am designing at 500 UPM). In the other masters, the same curve is 2 or 3 units deep. It would be impossible to work without a retracted BCP here. For the 2-unit deep curves, one could fiddle around with the horizontal length of the left handle (the height would have to be 1 anyway) to set the angle but I’d rather spend my time designing than fiddling.

What’s more, when interpolating, the left handle would have two additional rounding errors (x and y). With my retracted-BCP setup, we always have clean interpolation results. The x-direction rounding error of the free BCP does not spoil the smoothness of the shape. Of course, I extract the BCPs (on the basis of 1000 UPM) on export.

Also, I have many curves like this in the font, on nearly every terminal in every master. Using retracted BCPs makes it easy to keep the design consistent if I choose a handle length of roughly 60% for each. This would be much harder using two BCPs.

As a general rule, one should choose the minimum node/BCP setup that reflects the design intention. One would not insert a node into a curve if it is not necessary because it makes it more difficult to produce a simple curve if that is the intention. Creating and handling more degrees of freedom than necessary is always a bad thing. With a retracted BCP I have one degree of freedom, without there would be three.

This sounds very abstract to me. Note, we are not talking about storing shapes but about modifying them (i.e. designing), right? How would one modify the curve, i.e. visually choose the degree(s) of freedom, on the basis of your percentages, in practice? With a retracted BCP, one simply slides the remaining degree of freedom until one has found the desired shape. Using your percentage principles above, how does one design? Doesn’t it involve multiple steps for each change?

I never noticed that. Can you elaborate? Individual Bezier curve elements normally have a smooth curve transition within themselves by default. It can only gets unharmonious once you connect several curve elements.

Man, we are two days late with this discussion! Next year, I’ll go trick-or-treat dressed as a half-dead curve.

1 Like

Yeah, sorry, my mind was temporarily clouded :wink: Anyway, cubic Bézier with one or two zero handles are not problematic in Bézier mathematics, but only for incomplete algorithms that don’t expect them.

1 Like

I had a look at my TrueType code and could indeed improve it a bit. But it involves some guessing. Or does some has a good way to determine the angel of the first offcurve point? Normally it sits on the line of the Postscript offcurve handle. The actual tangent at the oncurve point is to far off.

This is the original code from RMX:

// extract retracted BCPs (unless both are retracted)
if ( node1.selected && node1 == bcp1 && node2 != bcp2 ) {
	// the intersection is moved by 5% and the relative handle length is 49%
	bcp1 = node1 * 0.51 + ( bcp2 * 0.95 + node2 * 0.05 ) * 0.49;
	// the length change of handle 2 is about 70%
	bcp2 = bcp2 * 0.707947 + node2 * 0.292053;
}

I found the figures by feeding the curve into my generic algorithm (that adjusts a curve to match another curve as closely as possible) but since they are essentially constants, independent of scale or proportions, I hard-coded them.

The 49% is arbitrarily chosen. The shorter handle 1, the closer the result would be to the original, of course, but we want a “proper” extraction, not merely fulfilling the condition that node1 != bcp1. If the grid is not 0 then bcp2 is later fitted again after bcp1 was (smartly, retaining the angle) rounded.

Thanks

My point exactly. How should the extraction algorithm work in this case? Are you using a grid subdivision? What should the algorithm do when the user is exporting it with a 1/1 grid? (Similar topic BTW, finer grids are also not very compatible.)

(For the record, I would probably not use an extremum during designing in this case.)

Please understand I am not saying you should not design like this. Fair enough if you design like this and a half-dead curve happens to fit your design intention and you are aware on what to do at export time. But (1) you can do that because you have sufficient technical knowledge, and (2) is there really one degree of freedom? There is really only one possible coordinate for the ‘leftover’ BCP, when ingoing and outgoing tangent angles are given, as in the vast majority of cases. I am counting exactly zero degrees of freedom.

The ‘fiddling’ has never been an issue in my workflow. What I want is a certain curve tension, and one-dimensional Fit Curve is great in that respect. Ctrl-Opt-1…8, harmonise if necessary, done. This clearly is not overcomplicating things, and you end up with a technically better BCP distribution. Here, I count one degree of freedom in choosing the curve tension. Which is something you need for making inside and outside curves fit each other.

You could not draw a proper lowercase o with retracted BCPs, unless you add on-curves at non-extremum positions. And that would really cause a lot of fiddling.

Sorry, I tried to be short and did not make myself clear enough. I was not talking about the design process, but about handle lengths and how to convert them with as little loss as possible, like the code snippet you posted. A technical thing, just like you expect no one to base their design decisions on the code snippet.

The point I was making is that if you look at a segment, the difference between the same overall tension, but evenly distributed handles, 1st BCP retracted, and 2nd BCP retracted, the difference between the three is unlikely to be a conscious design decision. Still, the even distribution has some advantages. Especially if you need to harmonise or interpolate afterwards.

Perhaps we draw the line between technical and design decision differently. But that is OK.

The angle between first oncurve and first offcurve, as well as last offcurve and last oncurve, should be equal in PS and TT. If there is only 1 offcurve visible in PS, use that offcurve for both angles. If no offcurve is visible in PS, it’s a line :wink:

If you are converting a PS segment into a TT segment with only 1 offcurve, its position is defined by the intersection point of the lines formed by PS oncurve1, offcurve1 and oncurve2, offcurve2. Unless again one of the PS offcurves is retracted, then use the other offcurve for both angles.

Depends on what you are trying to retain. If the aim is to retain the tangents at the nodes then your method is correct. If the aim is to retain the shape as closely as possible then your method does not give the best results.

The code from Tim helped a lot in improving the PS>TT conversion. And I also added support for inflections on variation export.