Merge pull request #5 from jackwakefield/ascent-descent
Added ascent and descent to text measurements
This commit is contained in:
commit
d877b57424
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
|
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 {
|
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
|
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},
|
Min: image.Point{X: xmin, Y: ymin},
|
||||||
Max: image.Point{X: xmax, Y: ymax}}
|
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)
|
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 {
|
if idx == 0 {
|
||||||
idx = fnt.Index(' ')
|
idx = fnt.Index(' ')
|
||||||
}
|
}
|
||||||
bounds, err := frc.glyphBounds(idx, p)
|
advance, bounds, err := frc.glyphMeasure(idx, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -108,10 +108,6 @@ func (cv *Canvas) FillText(str string, x, y float64) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
advance, err := frc.glyphAdvance(idx)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
textOffset.X = bounds.Min.X
|
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
|
// TextMetrics is the result of a MeasureText call
|
||||||
type TextMetrics struct {
|
type TextMetrics struct {
|
||||||
Width float64
|
Width float64
|
||||||
|
ActualBoundingBoxAscent float64
|
||||||
|
ActualBoundingBoxDescent float64
|
||||||
}
|
}
|
||||||
|
|
||||||
// MeasureText measures the given string using the
|
// MeasureText measures the given string using the
|
||||||
|
@ -248,7 +246,10 @@ func (cv *Canvas) MeasureText(str string) TextMetrics {
|
||||||
frc.setFontSize(float64(cv.state.fontSize))
|
frc.setFontSize(float64(cv.state.fontSize))
|
||||||
fnt := cv.state.font.font
|
fnt := cv.state.font.font
|
||||||
|
|
||||||
|
var p fixed.Point26_6
|
||||||
var x float64
|
var x float64
|
||||||
|
var minY float64
|
||||||
|
var maxY float64
|
||||||
prev, hasPrev := truetype.Index(0), false
|
prev, hasPrev := truetype.Index(0), false
|
||||||
for _, rn := range str {
|
for _, rn := range str {
|
||||||
idx := fnt.Index(rn)
|
idx := fnt.Index(rn)
|
||||||
|
@ -264,14 +265,26 @@ func (cv *Canvas) MeasureText(str string) TextMetrics {
|
||||||
}
|
}
|
||||||
x += float64(kern) / 64
|
x += float64(kern) / 64
|
||||||
}
|
}
|
||||||
advance, err := frc.glyphAdvance(idx)
|
|
||||||
|
advance, glyphBounds, err := frc.glyphMeasure(idx, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
prev = 0
|
prev = 0
|
||||||
hasPrev = false
|
hasPrev = false
|
||||||
continue
|
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
|
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