Added MeasureString
This commit is contained in:
parent
f29eb116de
commit
f412910dab
2 changed files with 65 additions and 12 deletions
|
@ -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)
|
||||
|
|
27
freetype.go
27
freetype.go
|
@ -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() {
|
||||
|
|
Loading…
Reference in a new issue