Involved Source Filescmap.godata.gogpos.gopostscript.go Package sfnt implements a decoder for TTF (TrueType Fonts) and OTF (OpenType
Fonts). Such fonts are also known as SFNT fonts.
This package provides a low-level API and does not depend on vector
rasterization packages. Glyphs are represented as vectors, not pixels.
The sibling golang.org/x/image/font/opentype package provides a high-level
API, including glyph rasterization.
This package provides a decoder in that it produces a TTF's glyphs (and
other metadata such as advance width and kerning pairs): give me the 'A'
from times_new_roman.ttf.
Unlike the image.Image decoder functions (gif.Decode, jpeg.Decode and
png.Decode) in Go's standard library, an sfnt.Font needs ongoing access to
the TTF data (as a []byte or io.ReaderAt) after the sfnt.ParseXxx functions
return. If parsing a []byte, its elements are assumed immutable while the
sfnt.Font remains in use. If parsing an *os.File, you should not close the
file until after you're done with the sfnt.Font.
The []byte or io.ReaderAt data given to ParseXxx can be re-written to
another io.Writer, copying the underlying TTF file, but this package does
not provide an encoder. Specifically, there is no API to build a different
TTF file, whether 'from scratch' or by modifying an existing one.truetype.go
Code Examples
package main
import (
"image"
"image/draw"
"log"
"os"
"golang.org/x/image/font/gofont/goregular"
"golang.org/x/image/font/sfnt"
"golang.org/x/image/math/fixed"
"golang.org/x/image/vector"
)
func main() {
const (
ppem = 32
width = 24
height = 36
originX = 0
originY = 32
)
// Load the 'G' glyph from the Go Regular font.
f, err := sfnt.Parse(goregular.TTF)
if err != nil {
log.Fatalf("Parse: %v", err)
}
var b sfnt.Buffer
x, err := f.GlyphIndex(&b, 'Ġ')
if err != nil {
log.Fatalf("GlyphIndex: %v", err)
}
if x == 0 {
log.Fatalf("GlyphIndex: no glyph index found for the rune 'Ġ'")
}
segments, err := f.LoadGlyph(&b, x, fixed.I(ppem), nil)
if err != nil {
log.Fatalf("LoadGlyph: %v", err)
}
// Translate and scale that glyph as we pass it to a vector.Rasterizer.
r := vector.NewRasterizer(width, height)
r.DrawOp = draw.Src
for _, seg := range segments {
// The divisions by 64 below is because the seg.Args values have type
// fixed.Int26_6, a 26.6 fixed point number, and 1<<6 == 64.
switch seg.Op {
case sfnt.SegmentOpMoveTo:
r.MoveTo(
originX+float32(seg.Args[0].X)/64,
originY+float32(seg.Args[0].Y)/64,
)
case sfnt.SegmentOpLineTo:
r.LineTo(
originX+float32(seg.Args[0].X)/64,
originY+float32(seg.Args[0].Y)/64,
)
case sfnt.SegmentOpQuadTo:
r.QuadTo(
originX+float32(seg.Args[0].X)/64,
originY+float32(seg.Args[0].Y)/64,
originX+float32(seg.Args[1].X)/64,
originY+float32(seg.Args[1].Y)/64,
)
case sfnt.SegmentOpCubeTo:
r.CubeTo(
originX+float32(seg.Args[0].X)/64,
originY+float32(seg.Args[0].Y)/64,
originX+float32(seg.Args[1].X)/64,
originY+float32(seg.Args[1].Y)/64,
originX+float32(seg.Args[2].X)/64,
originY+float32(seg.Args[2].Y)/64,
)
}
}
// Finish the rasterization: the conversion from vector graphics (shapes)
// to raster graphics (pixels).
dst := image.NewAlpha(image.Rect(0, 0, width, height))
r.Draw(dst, dst.Bounds(), image.Opaque, image.Point{})
// Visualize the pixels.
const asciiArt = ".++8"
buf := make([]byte, 0, height*(width+1))
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
a := dst.AlphaAt(x, y).A
buf = append(buf, asciiArt[a>>6])
}
buf = append(buf, '\n')
}
os.Stdout.Write(buf)
}
Collection is a collection of one or more fonts.
All of the Collection methods are safe to call concurrently. Font returns the i'th font in the collection. NumFonts returns the number of fonts in the collection.
func ParseCollection(src []byte) (*Collection, error)
func ParseCollectionReaderAt(src io.ReaderAt) (*Collection, error)
Font is an SFNT font.
Many of its methods take a *Buffer argument, as re-using buffers can reduce
the total memory allocation of repeated Font method calls, such as measuring
and rasterizing every unique glyph in a string of text. If efficiency is not
a concern, passing a nil *Buffer is valid, and implies using a temporary
buffer for a single call.
It is valid to re-use a *Buffer with multiple Font method calls, even with
different *Font receivers, as long as they are not concurrent calls.
All of the Font methods are safe to call concurrently, as long as each call
has a different *Buffer (or nil).
The Font methods that don't take a *Buffer argument are always safe to call
concurrently.
Some methods provide lengths or coordinates, e.g. bounds, font metrics and
control points. All of these methods take a ppem parameter, which is the
number of pixels in 1 em, expressed as a 26.6 fixed point value. For
example, if 1 em is 10 pixels then ppem is fixed.I(10), which equals
fixed.Int26_6(10 << 6).
To get those lengths or coordinates in terms of font units instead of
pixels, use ppem = fixed.Int26_6(f.UnitsPerEm()) and if those methods take a
font.Hinting parameter, use font.HintingNone. The return values will have
type fixed.Int26_6, but those numbers can be converted back to Units with no
further scaling necessary. Bounds returns the union of a Font's glyphs' bounds.
In the returned Rectangle26_6's (x, y) coordinates, the Y axis increases
down. GlyphAdvance returns the advance width for the x'th glyph. ppem is the
number of pixels in 1 em.
It returns ErrNotFound if the glyph index is out of range. GlyphBounds returns the bounding box of the x'th glyph, drawn at a dot equal
to the origin, and that glyph's advance width. ppem is the number of pixels
in 1 em.
It returns ErrNotFound if the glyph index is out of range.
The glyph's ascent and descent are equal to -bounds.Min.Y and +bounds.Max.Y.
The glyph's left-side and right-side bearings are equal to bounds.Min.X and
advance-bounds.Max.X. A visual depiction of what these metrics are is at
https://developer.apple.com/library/archive/documentation/TextFonts/Conceptual/CocoaTextArchitecture/Art/glyphterms_2x.png GlyphIndex returns the glyph index for the given rune.
It returns (0, nil) if there is no glyph for r.
https://www.microsoft.com/typography/OTSPEC/cmap.htm says that "Character
codes that do not correspond to any glyph in the font should be mapped to
glyph index 0. The glyph at this location must be a special glyph
representing a missing character, commonly known as .notdef." GlyphName returns the name of the x'th glyph.
Not every font contains glyph names. If not present, GlyphName will return
("", nil).
If present, the glyph name, provided by the font, is assumed to follow the
Adobe Glyph List Specification:
https://github.com/adobe-type-tools/agl-specification/blob/master/README.md
This is also known as the "Adobe Glyph Naming convention", the "Adobe
document [for] Unicode and Glyph Names" or "PostScript glyph names".
It returns ErrNotFound if the glyph index is out of range. Kern returns the horizontal adjustment for the kerning pair (x0, x1). A
positive kern means to move the glyphs further apart. ppem is the number of
pixels in 1 em.
It returns ErrNotFound if either glyph index is out of range. LoadGlyph returns the vector segments for the x'th glyph. ppem is the number
of pixels in 1 em.
If b is non-nil, the segments become invalid to use once b is re-used.
In the returned Segments' (x, y) coordinates, the Y axis increases down.
It returns ErrNotFound if the glyph index is out of range. It returns
ErrColoredGlyph if the glyph is not a monochrome vector glyph, such as a
colored (bitmap or vector) emoji glyph. Metrics returns the metrics of this font. Name returns the name value keyed by the given NameID.
It returns ErrNotFound if there is no value for that key. NumGlyphs returns the number of glyphs in f. PostTable returns the information from the font's "post" table. It can
return nil, if the font doesn't have such a table.
See https://docs.microsoft.com/en-us/typography/opentype/spec/post UnitsPerEm returns the number of units per em for f. WriteSourceTo writes the source data (the []byte or io.ReaderAt passed to
Parse or ParseReaderAt) to w.
It returns the number of bytes written. On success, this is the final offset
of the furthest SFNT table in the source. This may be less than the length
of the []byte or io.ReaderAt originally passed.
func Parse(src []byte) (*Font, error)
func ParseReaderAt(src io.ReaderAt) (*Font, error)
func (*Collection).Font(i int) (*Font, error)
PostTable represents an information stored in the PostScript font section. IsFixedPitch indicates that the font is not proportionally spaced
(i.e. monospaced). ItalicAngle in counter-clockwise degrees from the vertical. Zero for
upright text, negative for text that leans to the right (forward). UnderlinePosition is the suggested distance of the top of the
underline from the baseline (negative values indicate below baseline). Suggested values for the underline thickness. Version of the version tag of the "post" table.
func (*Font).PostTable() *PostTable
Segment is a segment of a vector path. Args is up to three (x, y) coordinates. The Y axis increases down. Op is the operator.
Units are an integral number of abstract, scalable "font units". The em
square is typically 1000 or 2048 "font units". This would map to a certain
number (e.g. 30 pixels) of physical pixels, depending on things like the
display resolution (DPI) and font size (e.g. a 12 point font).
func (*Font).UnitsPerEm() Units
Package-Level Functions (total 4)
Parse parses an SFNT font, such as TTF or OTF data, from a []byte data
source.
The caller should not modify src while the Font remains in use. See the
package documentation for details.
ParseCollection parses an SFNT font collection, such as TTC or OTC data,
from a []byte data source.
If passed data for a single font, a TTF or OTF instead of a TTC or OTC, it
will return a collection containing 1 font.
The caller should not modify src while the Collection or its Fonts remain in
use. See the package documentation for details.
ParseCollectionReaderAt parses an SFNT collection, such as TTC or OTC data,
from an io.ReaderAt data source.
If passed data for a single font, a TTF or OTF instead of a TTC or OTC, it
will return a collection containing 1 font.
The caller should not modify or close src while the Collection or its Fonts
remain in use. See the package documentation for details.
ParseReaderAt parses an SFNT font, such as TTF or OTF data, from an
io.ReaderAt data source.
The caller should not modify or close src while the Font remains in use. See
the package documentation for details.
Package-Level Variables (total 2)
ErrColoredGlyph indicates that the requested glyph is not a monochrome
vector glyph, such as a colored (bitmap or vector) emoji glyph.
ErrNotFound indicates that the requested value was not found.
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.