Reducing Glyph Widths on Either Side

Hi! I need help with some code, or a better solution for what I want to achieve.

I am trying to reduce the width of a bunch of glyphs that I select, based on a percentage value (97.8%). For example, if ‘n’ has a width of 462, then the resulting width should become 452. This is my code:

for layer in Font.selectedLayers:
glyph = layer.parent
for glyphLayer in glyph.layers:
layer.width = layer.width * 0.978

The problem is, this will reduce the width only from the right side of the glyph, so it will knock off 10 points from the right to make it 452. But I want the reduction to be distributed equally for a 10 point (even number) reduction. For odd numbers a single point either side is okay. Is there a (maybe even existing) way to do this?

(My thought for an algorithm is to keep a counter of 10 points and reduce the width from the LSB and RSB until the counter is down to 0.)

You just need to reduce the layer width as described, and then move the layer content (shapes, anchors) x-positions by half of that reduced width.

So, instead of changing the layer width right away, first calculate what x % of the width is in units, and then set the layer width to that units result and move the contentx-positions to half of that to the left.

1 Like

Wouldn’t that be easier?

diff = layer.width - layer.width * 0.978
layer.LSB -= diff/2
layer.RSB -= diff/2

This won’t work for odd number percentages right?

Edit: Wait, I think this makes a lot of sense. It’s pretty much doing the same thing I wrote but with fewer steps.

Currently I did this, which works. (It might be very roundabout, I’m not an experienced coder :P)

for layer in Font.selectedLayers:
	glyph = layer.parent
	for glyphLayer in glyph.layers:
		c = layer.width * 0.022
		c = round(c)

		switch = 0

		while c > 0:
			if switch == 0:
				glyphLayer.LSB-=1
				switch = 1
				c-=1

			if switch == 1:
				glyphLayer.RSB-=1
				switch = 0
				c-=1

Is there a keyword to target all of the content in that glyph; components, anchors and all?

You definitely don’t need a loop for this :slight_smile: Another way is to just set the width after the LSB, that might be 1 unit more precise:

percentage = 0.978
originalWidth = layer.width
diff = layer.width - layer.width * percentage
layer.LSB -= diff / 2
layer.width = originalWidth * percentage
1 Like

Normally, if you like to reduce the spacing of a font, it is better to apply an absolute value. Otherwise the change is quit uneven: much bigger for wider glyphs and less for narrow. And it can be done with Glyph > Transform Metrics.

But if you like to do percentage:

percentage = 0.978
width = Layer.width
diff = width * (1 - percentage) / 2.0
Layer.LSB -= diff
Layer.width -= diff
1 Like

Thanks Georg. I remember reading another Glyph forum thread on this, but that was only speaking of targeting the side bearings. (And it wouldn’t work for glyphs with 0 or negative side bearings.) I wanted to try to see if this approach could work if the width was targeted instead. I’m thinking of trying this as well as Transform Metrics and seeing which works better.

On another note, would anyone know how a software like Indesign reduces tracking? Say, when we set tracking manually to -10 in a text box. Does it remove five points from either side of every letter or does it use a percentage-wise method, or something else altogether?

I’m asking because somehow, a block of text in Indesign after -10 tracking looks better spaced than when I use Transform Metrics and knock off 5 points either side and then export the font to set that same text. I say this after having checked both in prints.

If you have set the spacing to “Metric” (and not “Optical”), adding a 10 units tracking should result in the same spacing then adding 10 units to the RSB (or 5 to each side).

1 Like

If your font has a upm of 1000

1 Like