Two new font production scripts.

blank's picture

I have released two font production scripts under the GPL. Both can be downloaded from

DTF Decomposer is a script intended for producing final versions of fonts that contain overlaps and composites that would otherwise require manual intervention. It first decomposes glyphs supplied in a list. It then removes overlaps in all glyphs and corrects path directions.

DTF Mark overlaps checks all glyphs for overlaps and marks a glyph when an overlap is found. It can find overlaps in glyphs that contain only outlines, only components, or outlines and components. It is not especially fast, but it is much faster than manual inspections. Sometimes glyphs that do not actually contain overlaps will be marked. This is because Fontlab's remove overlap function removes stray anchor points it deems unnecessary, such as anchor points on straight lines.

Neither script has been optimized to run as fast as it could, but they are both a lot faster than manual operations, especially when finishing families.

andreas's picture

Thank you!
The Mark Overlap is nice. It's runing now on a traced wood type design since 20 minits or so and is still runing. :-)

andreas's picture

So after an hour it's done. Your script is more precise like Fontlab itself on Type1 export.

Could it be it finds outlines that overlap not directly but one knot is placed on top of an other knot?

blank's picture

ould it be it finds outlines that overlap not directly but one knot is placed on top of an other knot?

It works by making two copies of a glyph. All components in each glyph are decomposed, then the remove overlaps function is applied to one copy. Then all anchor point locations in both copies are dumped to strings, the strings get hash()ed, and then the hashes are compared. If they don't match, the glyph is assumed to contain overlaps. The downside to this method is that glyphs with lots of anchor points will take a long time to check.

Jens Kutilek's picture

Hi James,

thanks for the idea about how to detect overlaps. I hope you don't mind, I rewrote your script to use pure FontLab, no RoboFab. That way it runs a lot faster. Additionally, I stop the comparison of points of a glyph as soon as a difference is found, that makes it faster too. And the last thing, you don't need to add the temporary glyphs to the font window. Drawing stuff on screen repeatedly makes things slow. I just make copies in memory using the copy constructors for Font() and Glyph(). The script now takes 1 second as compared to 258 seconds before on one of my fonts ;)

#FLM: Mark Overlaps JK

# make a copy of the current font
f = Font(fl.font)

for glyphIndex in range(len(f.glyphs)):
	g = f[glyphIndex]
	if len(g.components) > 1:
		# only decompose composites made up of more than one component
	if len(g) > 0:
		# glyph has outlines
		g2 = Glyph(g)
		if len(g) != len(g2):
			# different number of nodes
			fl.font[glyphIndex].mark = 10
			# check nodes
			for nodeIndex in range(len(g.nodes)):
				n = g.nodes[nodeIndex]
				n2 = g2.nodes[nodeIndex]
				if len(n) != len(n2):
					# nodes don't have the same number of points
					fl.font[glyphIndex].mark = 20
					# check points
					for pointIndex in range(len(n.points)):
						if n[pointIndex].x != n2[pointIndex].x or n[pointIndex].y != n2[pointIndex].y:
							fl.font[glyphIndex].mark = 30
blank's picture

Thanks, Jens. Your Fontlab coding abilities never fails to astound me!

Ramiro Espinoza's picture

Hi there,

Thanks for the different versions of the script. I've been using it today and I would like to point that although it does a fantastic work detecting overlapped components and contours, it does fail to detect when a component is overlapped by a contour. Can it be addressed as well?

Thanks in advance.


franchescaolsen's picture

well, I guess i should have checked this script on the first place that is why right now I am already looking forward into it.

Ramiro Espinoza's picture

Hi there,

Jens has updated the script and now it detect contours overlapping components as well. Thanks Jens again!

Just replace:

if len(g.components) > 1:


if (len(g.components) > 1) or (len(g) > 0 and len(g.components) > 0):

ferfolio's picture

The link doesn't seem to be working, any way I can get the scripts?


Ramiro Espinoza's picture

Copy the text Jens wrote and paste it in your FL's Python console. And replace the line I suggested if you wanna increase its functionality. Cheers.

Syndicate content Syndicate content