Merge pull request #5 from jackwakefield/ascent-descent

Added ascent and descent to text measurements
This commit is contained in:
Thomas Friedel 2018-05-21 00:23:19 +02:00 committed by GitHub
commit d877b57424
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 11 deletions

View file

@ -199,9 +199,9 @@ func (c *frContext) glyphAdvance(glyph truetype.Index) (fixed.Int26_6, error) {
return c.glyphBuf.AdvanceWidth, nil
}
func (c *frContext) glyphBounds(glyph truetype.Index, p fixed.Point26_6) (image.Rectangle, error) {
func (c *frContext) glyphMeasure(glyph truetype.Index, p fixed.Point26_6) (fixed.Int26_6, image.Rectangle, error) {
if err := c.glyphBuf.Load(c.f, c.scale, glyph, c.hinting); err != nil {
return image.Rectangle{}, err
return 0, image.Rectangle{}, err
}
fx := p.X & 0x3f
@ -214,7 +214,12 @@ func (c *frContext) glyphBounds(glyph truetype.Index, p fixed.Point26_6) (image.
Min: image.Point{X: xmin, Y: ymin},
Max: image.Point{X: xmax, Y: ymax}}
return bounds, nil
return c.glyphBuf.AdvanceWidth, bounds, nil
}
func (c *frContext) glyphBounds(glyph truetype.Index, p fixed.Point26_6) (image.Rectangle, error) {
_, bounds, err := c.glyphMeasure(glyph, p)
return bounds, err
}
const maxInt = int(^uint(0) >> 1)

27
text.go
View file

@ -86,7 +86,7 @@ func (cv *Canvas) FillText(str string, x, y float64) {
if idx == 0 {
idx = fnt.Index(' ')
}
bounds, err := frc.glyphBounds(idx, p)
advance, bounds, err := frc.glyphMeasure(idx, p)
if err != nil {
continue
}
@ -108,10 +108,6 @@ func (cv *Canvas) FillText(str string, x, y float64) {
break
}
advance, err := frc.glyphAdvance(idx)
if err != nil {
continue
}
if i == 0 {
textOffset.X = bounds.Min.X
}
@ -234,6 +230,8 @@ func (cv *Canvas) FillText(str string, x, y float64) {
// TextMetrics is the result of a MeasureText call
type TextMetrics struct {
Width float64
ActualBoundingBoxAscent float64
ActualBoundingBoxDescent float64
}
// MeasureText measures the given string using the
@ -248,7 +246,10 @@ func (cv *Canvas) MeasureText(str string) TextMetrics {
frc.setFontSize(float64(cv.state.fontSize))
fnt := cv.state.font.font
var p fixed.Point26_6
var x float64
var minY float64
var maxY float64
prev, hasPrev := truetype.Index(0), false
for _, rn := range str {
idx := fnt.Index(rn)
@ -264,14 +265,26 @@ func (cv *Canvas) MeasureText(str string) TextMetrics {
}
x += float64(kern) / 64
}
advance, err := frc.glyphAdvance(idx)
advance, glyphBounds, err := frc.glyphMeasure(idx, p)
if err != nil {
prev = 0
hasPrev = false
continue
}
if glyphMinY := float64(glyphBounds.Min.Y); glyphMinY < minY {
minY = glyphMinY
}
if glyphMaxY := float64(glyphBounds.Max.Y); glyphMaxY > maxY {
maxY = glyphMaxY
}
x += float64(advance) / 64
p.X += advance
}
return TextMetrics{Width: x}
return TextMetrics{
Width: x,
ActualBoundingBoxAscent: -minY,
ActualBoundingBoxDescent: +maxY,
}
}