Question about pixel fonts, instances and variable fonts

Hi!

I mostly create pixel fonts (8x8, recreations of old fonts from home computers). I used Glyphs Mini previously, but now got Glyphs 4.

I wanted to create 2 additional versions of a pixel font: one 50% width, and one 200% width, but overall, the same geometry. After reading a bit, I found out I could make that in the Export menu. So, I created a couple instances, applied a ScaleX transformation in the custom parameters of each instance (I only had to modify the grid subdivisions for the 50% instance from 1 to 2 to avoid distortions) and voila! I now have the three versions I wanted. Fantastic! :grin:

Now, my question is, is there a simple way like that to create a Variable font with a custom axis (basically a width axis with a different name) that achieves the same without having to create new Masters? I’ve been reading about Variable fonts, but pixel fonts have particular traits that leave me with lots of doubts, so that’s why I’m asking here.

If there is, I would greatly appreciate if you can point me to where I can read about how to make it (or what to pay attention to). If not, I’ll leave it as it is. Cheers!

Wouldn’t that variable font act exactly like if you would transform the font when you use the final font?

In essence, yes. And if you’re using a design program, there’s no need to lost time doing this.

But the different variations was asked by a user of the font for a retro site where having the 3 widths was convenient.

And making just a single variable font file was something I wanted to do to learn how to make variable fonts, and make the use of the font a bit more convenient. I also wanted to name the variations with a custom name as a nod to how they were called in the original computer (Mode 0 for the expanded, Mode 1 for the normal and Mode 2 for the condensed).

In case somebody is curious, the font is here: Dmian/font-cpc464: Pixel font based on Amstrad CPC 464 font - Codeberg.org

Cheers.

I see. It is not possible fully automatic. I’ll see if I can come up with some shortcuts.

1 Like

Oh! No, no, don’t need to do anything about it (unless you really want to and it benefits the app in any way). I just wanted to know if it was possible or not. Your answer is more than enough, thank you! :blush:

Edit: so, to make it clear, if I want to make a variable monospaced pixel font with different widths (or height, for that matter), I have to create different masters. For each of these masters I need to make a different pixel element, and assign it to each case (with “pixel=pixel.narrow” or “pixel=pixel.wide”, for example), and also a custom grid for each version (defined as Custom Parameter > Grid Main), to keep everything aligned properly. Is that right?

I may try that solution because I really want to learn how to do it. The app has a lot of different tools and customization options, and it’s neat to learn to use them. Cheers!

I’m working on something somewhat related with pixel fonts and variable axes, so I was wondering about this as well.

As far as I understand, the ScaleX transformation in an instance is great for generating the 50% and 200% versions, but a Variable Font axis normally needs actual master/design-space data to interpolate between. So I’m not sure whether there’s a way to get the same result with a custom axis without adding another master.

For pixel fonts, I’d also be concerned about interpolation introducing unwanted intermediate shapes or breaking the pixel grid. It would be really interesting to know if there’s a Glyphs-specific workflow for this, perhaps using a custom axis or some kind of export-time transformation.

If anyone has done something similar with pixel fonts, I’d love to hear how you approached it!

1 Like

Ok, I’m trying it out. So far what I’ve seen is: if you only want to change the width, like in my case, you clearly need to create a master for every width. I wanted double and half, so the changes I had to make were: define a new grid’s width & height (important!) for each master. The height I kept constant, while doubling or halving the width. Just redefining the grid’s width didn’t allow me to create rectangular pixels, only square ones.

And then I had to modify the pixel for each master.

After that, since I already had the glyphs, I had to rearrange the pixels in each master (except the original) to fall in the appropriate grid position, and adjust the final size.

Creating a font from scratch would be somewhat simpler, as you’ll have the correct grid and pixel from the beginning.

Any question, let me know. Cheers!

Here’s a little test for you. Get this font and drop it on https://fontgauntlet.com

CPC464VF.ttf (209.8 KB)

Leave just the “Ana” glyphs (the rest are still in progress). Move the “Mode” axis in the variable axes section. It interpolates well, as long as you rearrange the pixels to the correct positions.

I made another version, redrawing the “A” character, and the pixels danced everywhere!

So, as long as you take the same pixels as the original master, and position them in the exact same place, the font will interpolate as expected. :smiling_face::+1:

the quickest way to do this is by writing a vers small script that copies the content from the 100% master and scales it. So you only deal with the Regular masters and every time, before you export, run the script to update the other two masters.

1 Like

Thanks! I’ll check the scripting tutorial to see if I can learn how to do this. Cheers.

this script expects three masters. The first is the regular (100%) the second is the 50% and the third is the 200% …

from Cocoa import NSAffineTransform

mainMaster = Font.masters[0]
condensedMaster = Font.masters[1]
wideMaster = Font.masters[2]

condensedTransform = NSAffineTransform.new()
condensedTransform.scale((0.5, 1))
wideTransform = NSAffineTransform.new()
wideTransform.scale((2, 1))

for g in Font.glyphs:
	mainLayer = g.layers[mainMaster.id]
	condensedLayer = g.layers[condensedMaster.id]
	wideLayer = g.layers[wideMaster.id]
	
	copyLayer = mainLayer.copy()
	copyLayer.transform(condensedTransform)
	for component in copyLayer.components:
		component.scale = (1, 1)
	print(mainLayer.width, copyLayer.width)
	condensedLayer.width = copyLayer.width * 0.5
	condensedLayer.shapes = copyLayer.shapes
	
	copyLayer = mainLayer.copy()
	copyLayer.transform(wideTransform)
	for component in copyLayer.components:
		component.scale = (1, 1)
	wideLayer.width = copyLayer.width * 2
	wideLayer.shapes = copyLayer.shapes

1 Like

Oh! Thank you! This worked a treat! :blush:

I prepared the grids and masters in advance, run the script, and it created everything! Fantastic!
It had problems with a couple glyphs that were rotations of others, but it’s not a problem at all, as only a couple were created that way. So I’ll fix those manually.

I’ll see if I can adapt it to run only on a selected glyph, in case I want to update a glyph in particular.
But it’s so great! Thanks a lot. :hugs:

Edit: I need to learn to create scripts like this. I tried one following the examples from the tutorial, buy it didn’t work. :squinting_face_with_tongue:

Here is my test file. Check how I set the grid:
Pixel width.glyphs (6.8 KB)

Oh, yes, yes, don’t worry. It worked fantastically! The quirks are because I prefer to have no subdivision, to avoid misplacing pixels while drawing. That forces me to create custom rectangular grids for the wide and narrow masters. And since I don’t have a square grid to reference, it does weird things with rotated pixels, when trying to align them.

In the end, if I’m going to create more fonts like this, I need to take this into account, and probably avoid the rotate command (that makes sense for square pixels, but not rectangular ones) and use flip instead. (I hope I’m making sense :squinting_face_with_tongue:)

This is the final font:

CPC464VF.ttf (212.3 KB)

Thanks a lot, it’s been of enormous help, and I’ve learned a lot! Cheers.