func (f *Font) TextDimensions(text string) (int, int, int) { fnt := f.ttf size := f.Size var ( totalWidth = fixed.Int26_6(0) totalHeight = fixed.Int26_6(size) maxYBearing = fixed.Int26_6(0) ) fupe := fixed.Int26_6(fnt.FUnitsPerEm()) for _, char := range text { idx := fnt.Index(char) hm := fnt.HMetric(fupe, idx) vm := fnt.VMetric(fupe, idx) g := truetype.GlyphBuf{} err := g.Load(fnt, fupe, idx, font.HintingNone) if err != nil { log.Println(err) return 0, 0, 0 } totalWidth += hm.AdvanceWidth yB := (vm.TopSideBearing * fixed.Int26_6(size)) / fupe if yB > maxYBearing { maxYBearing = yB } } // Scale to actual pixel size totalWidth *= fixed.Int26_6(size) totalWidth /= fupe return int(totalWidth), int(totalHeight), int(maxYBearing) }
// our avatar image is square func (g *drawer) Draw(s string, size int, bg *color.RGBA) image.Image { // draw the background dst := image.NewRGBA(image.Rect(0, 0, size, size)) draw.Draw(dst, dst.Bounds(), &image.Uniform{bg}, image.ZP, draw.Src) // draw the text drawer := &font.Drawer{ Dst: dst, Src: image.White, Face: g.face, } // font index fi := g.font.Index([]rune(s)[0]) // glyph example: http://www.freetype.org/freetype2/docs/tutorial/metrics.png var gbuf truetype.GlyphBuf var err error var _fsize fixed.Int26_6 = fixed.Int26_6(g.fontSize * g.dpi * (64.0 / 72.0)) err = gbuf.Load(g.font, _fsize, fi, font.HintingFull) if err != nil { // fixme drawer.DrawString("") return dst } // center dY := int((size - int(gbuf.Bounds.Max.Y-gbuf.Bounds.Min.Y)>>6) / 2) dX := int((size - int(gbuf.Bounds.Max.X-gbuf.Bounds.Min.X)>>6) / 2) y := int(gbuf.Bounds.Max.Y>>6) + dY x := 0 - int(gbuf.Bounds.Min.X>>6) + dX //y := 10 + int(math.Ceil(g.fontSize*g.dpi/72)) //FIXME: what does it mean? drawer.Dot = fixed.Point26_6{ X: fixed.I(x), //(fixed.I(size) - drawer.MeasureString(s)) / 2, Y: fixed.I(y), } drawer.DrawString(s) return dst }