benoitkugler / textlayout

Fonts and text layout for Golang
MIT License
47 stars 7 forks source link

How can I extract the path data for an opentype font? #6

Closed whereswaldon closed 2 years ago

whereswaldon commented 2 years ago

In Gio, I'm currently parsing the font twice so that I have access to the actual glyph shapes. I parse it with the library here so that harfbuzz has the data that it needs, and I also parse it with sfnt because I know how to access the glyph path data there.

I couldn't figure out how to do so with the APIs in this module. Do you surface that information somewhere? I'm essentially looking for an analog of LoadGlyph. Sorry if I've missed it in the API!

benoitkugler commented 2 years ago

Short answer : there is indeed currently no equivalent of LoadGlyph in this project.

More precision : the main logic needed to retrieve glyph data is implemented, but, since I actually don't really need the glyph data for my personal projects, I have not exposed it yet. What makes things a bit complicated is that, even only considering Opentype fonts, there is at least three possible output format for glyphs :

I've started to think about a possible API to expose glyph data. I was thinking about :

// FaceRenderer exposes access to glyph contents
type FaceRenderer interface {
    // GlyphData loads the glyph content, or return nil
    // if 'gid' is not supported.
    // For bitmap glyphs, the closest resolution to `xPpem` and `yPpem` is selected.
    GlyphData(gid GID, xPpem, yPpem uint16) GlyphData
}

// GlyphData describe how to graw a glyph.
// It is either an GlyphOutline, GlyphSVG or GlyphBitmap.
type GlyphData interface {
    isGlyphData()
}

type GlyphOutline struct { // TODO:
}

type GlyphSVG struct {
    Source []byte // The SVG image content
}

type GlyphBitmap struct {
    // The actual image content, whose interpretation depends
    // on the Format field.
    Data          []byte
    Format        BitmapFormat
    Width, Height int // number of columns and rows
}

// BitmapFormat identifies the format on the glyph
// raw data. Across the various font files, many formats
// may be encountered : black and white bitmaps, PNG, TIFF, JPG.
type BitmapFormat uint8

const (
    _ BitmapFormat = iota
    BlackAndWhite
    PNG
    JPG
    TIFF
)

I'm definitively open to suggestions and ideas to add this to this package. Actually, what I probably could do is to implement the GlyphOutline type above matching as closely as possible the sfnt.Segments type. What do you think ?

benoitkugler commented 2 years ago

I have implemented the above approach in the latest commits (v0.0.5). You would call Face.GlyphData(gid, 0,0) and type assert to GlyphOutline to get the (unscaled) Segments. Tell me if this suits your needs.

whereswaldon commented 2 years ago

This does suit my needs very well. Thanks a bunch for putting this together!