Added MeasureString

This commit is contained in:
Leonel 2015-12-11 14:02:34 -02:00
parent f29eb116de
commit f412910dab
2 changed files with 65 additions and 12 deletions

View file

@ -33,6 +33,7 @@ var (
size = flag.Float64("size", 12, "font size in points")
spacing = flag.Float64("spacing", 1.5, "line spacing (e.g. 2 means double spaced)")
wonb = flag.Bool("whiteonblack", false, "white text on a black background")
bound = flag.Bool("bound", false, "generates image with minimum size for the text")
)
var text = []string{
@ -88,21 +89,10 @@ func main() {
}
// Initialize the context.
fg, bg := image.Black, image.White
ruler := color.RGBA{0xdd, 0xdd, 0xdd, 0xff}
if *wonb {
fg, bg = image.White, image.Black
ruler = color.RGBA{0x22, 0x22, 0x22, 0xff}
}
rgba := image.NewRGBA(image.Rect(0, 0, 640, 480))
draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src)
c := freetype.NewContext()
c.SetDPI(*dpi)
c.SetFont(f)
c.SetFontSize(*size)
c.SetClip(rgba.Bounds())
c.SetDst(rgba)
c.SetSrc(fg)
switch *hinting {
default:
c.SetHinting(font.HintingNone)
@ -110,6 +100,44 @@ func main() {
c.SetHinting(font.HintingFull)
}
var width, height int
// Measure the text to calculate the minimum size of the image
if *bound {
x := 0
pt := freetype.Pt(10, 10+int(c.PointToFixed(*size)>>6))
for _, s := range text {
ptr, err := c.MeasureString(s, pt)
if err != nil {
log.Println(err)
return
}
pt.Y += c.PointToFixed(*size * *spacing)
x = int(ptr.X >> 6)
if x > width {
width = x
}
}
width += 10
height = int(pt.Y)>>6 - int(c.PointToFixed(*size)>>6)
// Use default size for the image
} else {
width = 640
height = 480
}
// Creates image with the specified size
fg, bg := image.Black, image.White
ruler := color.RGBA{0xdd, 0xdd, 0xdd, 0xff}
if *wonb {
fg, bg = image.White, image.Black
ruler = color.RGBA{0x22, 0x22, 0x22, 0xff}
}
rgba := image.NewRGBA(image.Rect(0, 0, width, height))
draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src)
c.SetClip(rgba.Bounds())
c.SetDst(rgba)
c.SetSrc(fg)
// Draw the guidelines.
for i := 0; i < 200; i++ {
rgba.Set(10, 10+i, ruler)

View file

@ -229,7 +229,7 @@ func (c *Context) glyph(glyph truetype.Index, p fixed.Point26_6) (
// p is a fixed.Point26_6 and can therefore represent sub-pixel positions.
func (c *Context) DrawString(s string, p fixed.Point26_6) (fixed.Point26_6, error) {
if c.f == nil {
return fixed.Point26_6{}, errors.New("freetype: DrawText called with a nil font")
return fixed.Point26_6{}, errors.New("freetype: DrawString called with a nil font")
}
prev, hasPrev := truetype.Index(0), false
for _, rune := range s {
@ -257,6 +257,31 @@ func (c *Context) DrawString(s string, p fixed.Point26_6) (fixed.Point26_6, erro
return p, nil
}
// MeasureString is identical to DrawString but only measure the text.
func (c *Context) MeasureString(s string, p fixed.Point26_6) (fixed.Point26_6, error) {
if c.f == nil {
return fixed.Point26_6{}, errors.New("freetype: MeasureString called with a nil font")
}
prev, hasPrev := truetype.Index(0), false
for _, rune := range s {
index := c.f.Index(rune)
if hasPrev {
kern := c.f.Kern(c.scale, prev, index)
if c.hinting != font.HintingNone {
kern = (kern + 32) &^ 63
}
p.X += kern
}
advanceWidth, _, _, err := c.glyph(index, p)
if err != nil {
return fixed.Point26_6{}, err
}
p.X += advanceWidth
prev, hasPrev = index, true
}
return p, nil
}
// recalc recalculates scale and bounds values from the font size, screen
// resolution and font metrics, and invalidates the glyph cache.
func (c *Context) recalc() {