Creating Grades and inheriting metrics

Hiya,
I am working in a font, two masters, weight axis, several instances.
I would like to create instances that have slightly different position in the weight axis, but that share glyph width metrics, (i.e. grades). Obviously the difference substracted in the sidebearings would have to be proportional in both sides. Is there any fast way of doing this or do you know of anyone who came up with a script for this? In order to be fully efficient, this probably wouldn’t have to be a script but some kind of integration in the export process, so it all can happen automatically and the user only needs to worry about checking the weight difference

Thanks

can you describe the master setup and the result in a bit more detail?

Of course,
M1(75)-------F1a(92)–F1b(97)-----------F2a(128)–F2b(140)------------------------ M2 (185)

It would be something like this, where M1 & M2 are the masters, this is the weight axis, and I have F1a and F2a. Since I want to create “grades”, I would like to be able to create F1b and F2b, which are slightly heavier than the ‘a’ ones, but in order to function properly as grades I need the overall width of each individual glyph to match (between F1a and F1b; and bethween F2a and F2b). Since both 'b’s are slightly heavier the sidebearing values will be different but I need that difference to be evenly distributed, meaning. If ‘D’ in F1a has sidebeadings of 40 and 25, with an overall glyph width of 525, I will need F1b with (random values) 35 and 20, but an overall glyph width of 525. Does this make more sense??

Thanks

‘F’ are instances? The only way I can see how that could work is by writing a Filter plugin that is applied on export.

Yeah, F are instances, and yeah I agree about the filer thing in export. My question is, anybody around knows if this has been done already?

That is a quite special use case so I don’t think that someone has done it already.

What I would do (but don’t have time for it right now):

  1. The filter needs the target coordinates as input.
  2. for each layer, it needs to interpolate the same glyph for the other instance (but can’t rely on that instance directly). So you need to make your own instance and use the instance.interpolatedFontProxy to get to the interpolated layers.
  3. calculate the difference and add evenly to the side bearings. You could do it proportionally (add more to larger numbers) but in your case that would make very little difference.

Thanks Georg, you are a star.
I will see if I can figure out how to do it. You might wanna consider include it in the regular workflow of Glyphs. Newspaper grades, Negative UIs, Negative Wayfinding… there is a large number of type applications that would benefit of this feature.

Cheers!

Did you end up making that plugin?
I’ve had ideas about similar family plans where some styles should be compatible in width.
The tool I had in mind at the time would be a little more complex as simply taking all the advance widths of one instance and applying them to another might in some cases have unwanted consequences, ex: a glyph where too much space is removed, ending up with negative sidebearings.
It should have an option to instead distribute the spacing evenly between all instances (potentially more than two) that are part of a « grade », meaning that in your exemple, F1a and F1b would both have their widths changed to an intermediate value between the two (or another ratio, could be user-defined between 0 and 1). If you have more instances in between, the plugin should figure out what the « extremes » are for a grade, on all axes. Kerning should be affected too.

Anyway, I didn’t have plans to make this right now but if that sounds like the tool you need and you haven’t yet made your own version, I’m okay to do it as I will have use for it later.

Hi Joachim!
Thanks for the interest on this. Nope, I haven’t started yet working on this. It is all part of a bigger master plan and I still have many loose ends to work on. Plus my programming skills are extremely limited so it would take me some good time to figure it out :slight_smile: But if you are up for it, I am up to help you! what do you need? Is there anything I can do to support you? The additional options you mention sound interesting but are definetly too much for my project, that only has a single axis and the distance between instances are supossed to be small enough so there will not be those spacing issues.

Just a quick thought here, maybe a way to bypass the issue of creating instances with negative sidebearing could be by forcing the user to create always the instance from heavy to light instead of light to heavy. Let me clarify. In the example I showed earlier, if I have F1a and I want F1b (slightly heavier with F1a glyph width applied) I might have those negative sidebearings issues, specially if my spacing is really tight. However, if I have F1b and I create F1a (with f1b glyph width metrics), I will not have those problems. Forcing user’s behaviours is never cool, but it might be if it saves you tons of programming time :slight_smile:

So! What’s next??

It’s not that much more work to be able to select a position in the design space that serves as a basis for all instances belonging to the same grade range.

My only concern is that because filters are applied on every layer, the operation of creating a new base instance and copying its kerning will be repeated over and over again for each glyph of a font. Not very performance friendly when I would only need to create the instance once, copying the kerning, and only then apply the new widths to all layers.

I wish there was a way to create specific custom parameters outside of the scope of a Filter plugin that is applied on a layer basis. Is this something that is possible @GeorgSeifert?

Actually I did
It was a commissioned gig though. Took a lot of time.
Still got the pieces laying around, but cannot give it away just as is, but maybe we can figure sth out.

Speaking with your client, marketing the stuff as one of your plugins, and offering them a cut? :thinking:

@georg, I tried messing around with stuff and I have some weird issues with FilterWithoutDialog:

  • i was expecting that, but creating a GSInstance() object in filter() crashes Glyphs
  • deleting the instance at the end of filter works, but…
  • trying to access interpolatedFontProxy crashes Glyphs after a while (I’m printing the object and can see that Glyphs crashes after a few iterations of filter()

Creating an instance on each filter() call doesn’t make much sense anyway, but there doesn’t seem to be a method in FilterWithoutDialog that is called once before all the filter() calls, but after init

  • I’m not sure I get what the differences are between settings, start, loadPlugin. They all seem to be called when Glyphs launches, so before a font is opened.
  • I tried initializing an empty variable in all of these methods, and assigning an instance to it at the first filter call, to then reference that instance for each following call. That crashes Glyphs directly when trying to generate fonts.
  • the error message I get when restarting Glyphs is always the same, whatever the type of error I’m throwing at it, which makes debugging quite difficult:
    *** Terminating app due to uncaught exception 'OC_PythonException', reason: '<type 'exceptions.AttributeError'>: 'Grader' object has no attribute 'menuName''
    (I do have a menuName parameter in my settings function)

Because Glyphs crashes before I even start to actually do anything I’m not really sure how to proceed from here. Should I use a FilterWithoutDialog? I don’t even need a Filter menu item, I just want to make a custom parameter that runs upon exporting.

Can you send me what you have that I can have a look?

1 Like

Should have read the plugins wrapper, it had everything I needed.
@pbeaujon, its dirty and needs cleaning up but should work if you want to give it a try: GitHub
@GeorgSeifert can I somehow turn this into a custom parameter only since there’s no need for a filter menu access?