Source File
font.go
Belonging Package
golang.org/x/image/font
// Copyright 2015 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.// Package font defines an interface for font faces, for drawing text on an// image.//// Other packages provide font face implementations. For example, a truetype// package would provide one based on .ttf font files.package font // import "golang.org/x/image/font"import ()// TODO: who is responsible for caches (glyph images, glyph indices, kerns)?// The Drawer or the Face?// Face is a font face. Its glyphs are often derived from a font file, such as// "Comic_Sans_MS.ttf", but a face has a specific size, style, weight and// hinting. For example, the 12pt and 18pt versions of Comic Sans are two// different faces, even if derived from the same font file.//// A Face is not safe for concurrent use by multiple goroutines, as its methods// may re-use implementation-specific caches and mask image buffers.//// To create a Face, look to other packages that implement specific font file// formats.type Face interface {io.Closer// Glyph returns the draw.DrawMask parameters (dr, mask, maskp) to draw r's// glyph at the sub-pixel destination location dot, and that glyph's// advance width.//// It returns !ok if the face does not contain a glyph for r. This includes// returning !ok for a fallback glyph (such as substituting a U+FFFD glyph// or OpenType's .notdef glyph), in which case the other return values may// still be non-zero.//// The contents of the mask image returned by one Glyph call may change// after the next Glyph call. Callers that want to cache the mask must make// a copy.Glyph(dot fixed.Point26_6, r rune) (dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool)// GlyphBounds returns the bounding box of r's glyph, drawn at a dot equal// to the origin, and that glyph's advance width.//// It returns !ok if the face does not contain a glyph for r. This includes// returning !ok for a fallback glyph (such as substituting a U+FFFD glyph// or OpenType's .notdef glyph), in which case the other return values may// still be non-zero.//// 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.pngGlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool)// GlyphAdvance returns the advance width of r's glyph.//// It returns !ok if the face does not contain a glyph for r. This includes// returning !ok for a fallback glyph (such as substituting a U+FFFD glyph// or OpenType's .notdef glyph), in which case the other return values may// still be non-zero.GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool)// Kern returns the horizontal adjustment for the kerning pair (r0, r1). A// positive kern means to move the glyphs further apart.Kern(r0, r1 rune) fixed.Int26_6// Metrics returns the metrics for this Face.Metrics() Metrics// TODO: ColoredGlyph for various emoji?// TODO: Ligatures? Shaping?}// Metrics holds the metrics for a Face. A visual depiction is at// https://developer.apple.com/library/mac/documentation/TextFonts/Conceptual/CocoaTextArchitecture/Art/glyph_metrics_2x.pngtype Metrics struct {// Height is the recommended amount of vertical space between two lines of// text.Height fixed.Int26_6// Ascent is the distance from the top of a line to its baseline.Ascent fixed.Int26_6// Descent is the distance from the bottom of a line to its baseline. The// value is typically positive, even though a descender goes below the// baseline.Descent fixed.Int26_6// XHeight is the distance from the top of non-ascending lowercase letters// to the baseline.XHeight fixed.Int26_6// CapHeight is the distance from the top of uppercase letters to the// baseline.CapHeight fixed.Int26_6// CaretSlope is the slope of a caret as a vector with the Y axis pointing up.// The slope {0, 1} is the vertical caret.CaretSlope image.Point}// Drawer draws text on a destination image.//// A Drawer is not safe for concurrent use by multiple goroutines, since its// Face is not.type Drawer struct {// Dst is the destination image.Dst draw.Image// Src is the source image.Src image.Image// Face provides the glyph mask images.Face Face// Dot is the baseline location to draw the next glyph. The majority of the// affected pixels will be above and to the right of the dot, but some may// be below or to the left. For example, drawing a 'j' in an italic face// may affect pixels below and to the left of the dot.Dot fixed.Point26_6// TODO: Clip image.Image?// TODO: SrcP image.Point for Src images other than *image.Uniform? How// does it get updated during DrawString?}// TODO: should DrawString return the last rune drawn, so the next DrawString// call can kern beforehand? Or should that be the responsibility of the caller// if they really want to do that, since they have to explicitly shift d.Dot// anyway? What if ligatures span more than two runes? What if grapheme// clusters span multiple runes?//// TODO: do we assume that the input is in any particular Unicode Normalization// Form?//// TODO: have DrawRunes(s []rune)? DrawRuneReader(io.RuneReader)?? If we take// io.RuneReader, we can't assume that we can rewind the stream.//// TODO: how does this work with line breaking: drawing text up until a// vertical line? Should DrawString return the number of runes drawn?// DrawBytes draws s at the dot and advances the dot's location.//// It is equivalent to DrawString(string(s)) but may be more efficient.func ( *Drawer) ( []byte) {:= rune(-1)for len() > 0 {, := utf8.DecodeRune()= [:]if >= 0 {.Dot.X += .Face.Kern(, )}, , , , := .Face.Glyph(.Dot, )if !.Empty() {draw.DrawMask(.Dst, , .Src, image.Point{}, , , draw.Over)}.Dot.X +==}}// DrawString draws s at the dot and advances the dot's location.func ( *Drawer) ( string) {:= rune(-1)for , := range {if >= 0 {.Dot.X += .Face.Kern(, )}, , , , := .Face.Glyph(.Dot, )if !.Empty() {draw.DrawMask(.Dst, , .Src, image.Point{}, , , draw.Over)}.Dot.X +==}}// BoundBytes returns the bounding box of s, drawn at the drawer dot, as well as// the advance.//// It is equivalent to BoundBytes(string(s)) but may be more efficient.func ( *Drawer) ( []byte) ( fixed.Rectangle26_6, fixed.Int26_6) {, = BoundBytes(.Face, ).Min = .Min.Add(.Dot).Max = .Max.Add(.Dot)return}// BoundString returns the bounding box of s, drawn at the drawer dot, as well// as the advance.func ( *Drawer) ( string) ( fixed.Rectangle26_6, fixed.Int26_6) {, = BoundString(.Face, ).Min = .Min.Add(.Dot).Max = .Max.Add(.Dot)return}// MeasureBytes returns how far dot would advance by drawing s.//// It is equivalent to MeasureString(string(s)) but may be more efficient.func ( *Drawer) ( []byte) ( fixed.Int26_6) {return MeasureBytes(.Face, )}// MeasureString returns how far dot would advance by drawing s.func ( *Drawer) ( string) ( fixed.Int26_6) {return MeasureString(.Face, )}// BoundBytes returns the bounding box of s with f, drawn at a dot equal to the// origin, as well as the advance.//// It is equivalent to BoundString(string(s)) but may be more efficient.func ( Face, []byte) ( fixed.Rectangle26_6, fixed.Int26_6) {:= rune(-1)for len() > 0 {, := utf8.DecodeRune()= [:]if >= 0 {+= .Kern(, )}, , := .GlyphBounds()if !.Empty() {.Min.X +=.Max.X +== .Union()}+==}return}// BoundString returns the bounding box of s with f, drawn at a dot equal to the// origin, as well as the advance.func ( Face, string) ( fixed.Rectangle26_6, fixed.Int26_6) {:= rune(-1)for , := range {if >= 0 {+= .Kern(, )}, , := .GlyphBounds()if !.Empty() {.Min.X +=.Max.X +== .Union()}+==}return}// MeasureBytes returns how far dot would advance by drawing s with f.//// It is equivalent to MeasureString(string(s)) but may be more efficient.func ( Face, []byte) ( fixed.Int26_6) {:= rune(-1)for len() > 0 {, := utf8.DecodeRune()= [:]if >= 0 {+= .Kern(, )}, := .GlyphAdvance()+==}return}// MeasureString returns how far dot would advance by drawing s with f.func ( Face, string) ( fixed.Int26_6) {:= rune(-1)for , := range {if >= 0 {+= .Kern(, )}, := .GlyphAdvance()+==}return}// Hinting selects how to quantize a vector font's glyph nodes.//// Not all fonts support hinting.type Hinting intconst (HintingNone Hinting = iotaHintingVerticalHintingFull)// Stretch selects a normal, condensed, or expanded face.//// Not all fonts support stretches.type Stretch intconst (StretchUltraCondensed Stretch = -4StretchExtraCondensed Stretch = -3StretchCondensed Stretch = -2StretchSemiCondensed Stretch = -1StretchNormal Stretch = +0StretchSemiExpanded Stretch = +1StretchExpanded Stretch = +2StretchExtraExpanded Stretch = +3StretchUltraExpanded Stretch = +4)// Style selects a normal, italic, or oblique face.//// Not all fonts support styles.type Style intconst (StyleNormal Style = iotaStyleItalicStyleOblique)// Weight selects a normal, light or bold face.//// Not all fonts support weights.//// The named Weight constants (e.g. WeightBold) correspond to CSS' common// weight names (e.g. "Bold"), but the numerical values differ, so that in Go,// the zero value means to use a normal weight. For the CSS names and values,// see https://developer.mozilla.org/en/docs/Web/CSS/font-weighttype Weight intconst (WeightThin Weight = -3 // CSS font-weight value 100.WeightExtraLight Weight = -2 // CSS font-weight value 200.WeightLight Weight = -1 // CSS font-weight value 300.WeightNormal Weight = +0 // CSS font-weight value 400.WeightMedium Weight = +1 // CSS font-weight value 500.WeightSemiBold Weight = +2 // CSS font-weight value 600.WeightBold Weight = +3 // CSS font-weight value 700.WeightExtraBold Weight = +4 // CSS font-weight value 800.WeightBlack Weight = +5 // CSS font-weight value 900.)
![]() |
The pages are generated with Golds v0.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. |