googlefonts / fontc

Where in we pursue oxidizing (context: https://github.com/googlefonts/oxidize) fontmake.
Apache License 2.0
85 stars 14 forks source link

Certain deltas crash IUP optimisation #1116

Open Hoolean opened 1 week ago

Hoolean commented 1 week ago

Hello again - we observed one other issue when trying to experimentally compile one of our larger library fonts with fontc at Dalton Maag.

A particular arrangement of deltas succeeds with fontmake but crashes fontc compilation with an IUP error:

[... ThreadId(1) fontc ERROR] IUP error for glyph: AchievedInvalidState("No best solution identified")
error: process didn't exit successfully: `...\fontc.exe .../Deltas.designspace` (exit code: 1)

Reproducing

As with the earlier issue (#1115), the original font is proprietary and so we've made an independent minimal reproducer to share and use here.

Deltas that trigger the IUP crash

(more minimal deltas are probably possible, but at this point I struggled to

use fewer while still triggering the crash)

DELTAS = [ Point(x=0, y=0, type="line"), Point(x=1, y=0, type="line"), Point(x=1, y=0, type="line"), Point(x=0, y=1, type="line"), Point(x=0, y=0, type="line"), Point(x=1, y=0, type="line"), Point(x=1, y=3, type="line"), Point(x=2, y=0, type="line"), Point(x=2, y=3, type="line"), Point(x=0, y=0, type="line"), Point(x=0, y=0, type="line"), Point(x=0, y=3, type="line"), ]

Create designspace with weight axis

doc = DesignSpaceDocument() doc.addAxis( AxisDescriptor(tag="wght", name="Weight", minimum=400, maximum=700, default=400) )

Create a glyph with all points at origin in one source, and all points at

particular offsets in another.

for style, weight, points in [ ("Regular", 400, DELTAS), ("Bold", 700, [Point(x=0, y=0, type="line") for _ in range(len(DELTAS))]), ]: ufo = Font()

inner = ufo.newGlyph("glyph")
inner.contours.append(Contour(points))

ufo.save(f"{style}.ufo", overwrite=True)

doc.addSource(SourceDescriptor(path=f"{style}.ufo", location={"Weight": weight}))
doc.addInstance(InstanceDescriptor(styleName=style, location={"Weight": weight}))

doc.write("Deltas.designspace")

Hoolean commented 1 week ago

(this is a stab in the dark as I'm not able to investigate further at this time, but could this conditional before the error have an off-by-one? it looks like <= might be needed instead of < to only catch the cases where the index would be negative)