go-text / typesetting

High quality text shaping in pure Go.
Other
101 stars 10 forks source link

fontscan doesn't have a way to detect whether the face is monotype or not #113

Closed hajimehoshi closed 6 months ago

hajimehoshi commented 10 months ago

https://pkg.go.dev/github.com/go-text/typesetting@v0.0.0-20231120180320-af78120ccb13/fontscan#FontMap.FontMetadata

FontMetadata returns a family name and an aspect, but doesn't return whether the font is monospace or not.

https://pkg.go.dev/github.com/go-text/typesetting@v0.0.0-20231120180320-af78120ccb13/opentype/api/metadata#Metadata

When a font is loaded via a loader, it is possible to know the monospace info.

Would it be possible to get this info via fontscan?

hajimehoshi commented 10 months ago

Just out of curiosity, why doesn't font.Face have metadata info?

benoitkugler commented 10 months ago

Just out of curiosity, why doesn't font.Face have metadata info?

The metadata information are not required to shape/render glyphs, which is the primary job of face.Face. So it is about separation of concerns.

benoitkugler commented 10 months ago

https://pkg.go.dev/github.com/go-text/typesetting@v0.0.0-20231120180320-af78120ccb13/fontscan#FontMap.FontMetadata

FontMetadata returns a family name and an aspect, but doesn't return whether the font is monospace or not.

https://pkg.go.dev/github.com/go-text/typesetting@v0.0.0-20231120180320-af78120ccb13/opentype/api/metadata#Metadata

When a font is loaded via a loader, it is possible to know the monospace info.

We initially thought about adding this information into the query, but it turns out that :

Would it be possible to get this info via fontscan?

So the idea is that we could, but it is not clear if we should. Is using the generic monospace family a decent solution for you ? Said otherwise, what would be your use case that really requires this property ?

hajimehoshi commented 10 months ago

The metadata information are not required to shape/render glyphs, which is the primary job of face.Face. So it is about separation of concerns.

Wouldn't it be more natural that the metadata belongs to font faces, rather than how to load them?

Said otherwise, what would be your use case that really requires this property ?

I don't know, maybe I don't have actual usecases, but I felt this being a little inconsistent.

whereswaldon commented 10 months ago

https://pkg.go.dev/github.com/go-text/typesetting@v0.0.0-20231120180320-af78120ccb13/fontscan#FontMap.FontMetadata

FontMetadata returns a family name and an aspect, but doesn't return whether the font is monospace or not.

https://pkg.go.dev/github.com/go-text/typesetting@v0.0.0-20231120180320-af78120ccb13/opentype/api/metadata#Metadata

When a font is loaded via a loader, it is possible to know the monospace info.

This is a mistake. We used to surface this info in the metadata (I naively pushed for it), but it was incredibly expensive to compute whether a font was actually monospace. You basically have to iterate all glyphs within the font checking for uniform width, and that's prohibitively expensive to do on all system fonts.

We should probably remove the field from the Metadata struct entirely. It isn't clear to the caller that requesting the metadata will trigger an expensive scan of font data.

Wouldn't it be more natural that the metadata belongs to font faces, rather than how to load them?

I've never found separating them to be especially useful either. I usually need the description/metadata everywhere in my code that I manage fonts, so I have to plumb them alongside one another. I would have no objection to combining them somehow.

benoitkugler commented 6 months ago

130 has added two methods (*Font) IsMonospace() bool and (*Font) Describe() Description which should help with this issue.

So I'm closing it for now, feel free to reopen if you feel there is still something actionnable to discuss.