added ascent and descent to text measurements
This commit is contained in:
parent
7d87ef795a
commit
a3cc04778f
2 changed files with 29 additions and 11 deletions
11
freetype.go
11
freetype.go
|
@ -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
27
text.go
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue