Implement GlyphBounds and GlyphAdvance.
This commit is contained in:
parent
9c46b87503
commit
24265d1c91
2 changed files with 51 additions and 11 deletions
|
@ -37,6 +37,8 @@ var (
|
|||
wonb = flag.Bool("whiteonblack", false, "white text on a black background")
|
||||
)
|
||||
|
||||
const title = "Jabberwocky"
|
||||
|
||||
var text = []string{
|
||||
"’Twas brillig, and the slithy toves",
|
||||
"Did gyre and gimble in the wabe;",
|
||||
|
@ -96,7 +98,8 @@ func main() {
|
|||
fg, bg = image.White, image.Black
|
||||
ruler = color.RGBA{0x22, 0x22, 0x22, 0xff}
|
||||
}
|
||||
rgba := image.NewRGBA(image.Rect(0, 0, 640, 480))
|
||||
const imgW, imgH = 640, 480
|
||||
rgba := image.NewRGBA(image.Rect(0, 0, imgW, imgH))
|
||||
draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src)
|
||||
for i := 0; i < 200; i++ {
|
||||
rgba.Set(10, 10+i, ruler)
|
||||
|
@ -118,11 +121,18 @@ func main() {
|
|||
Hinting: h,
|
||||
}),
|
||||
}
|
||||
dy0 := int(math.Ceil(*size * *dpi / 72))
|
||||
y := 10 + int(math.Ceil(*size**dpi/72))
|
||||
dy := int(math.Ceil(*size * *spacing * *dpi / 72))
|
||||
for i, s := range text {
|
||||
d.Dot = fixed.P(10, 10+dy0+i*dy)
|
||||
d.Dot = fixed.Point26_6{
|
||||
X: (fixed.I(imgW) - d.MeasureString(title)) / 2,
|
||||
Y: fixed.I(y),
|
||||
}
|
||||
d.DrawString(title)
|
||||
y += dy
|
||||
for _, s := range text {
|
||||
d.Dot = fixed.P(10, y)
|
||||
d.DrawString(s)
|
||||
y += dy
|
||||
}
|
||||
|
||||
// Save that RGBA image to disk.
|
||||
|
|
|
@ -132,6 +132,36 @@ func (a *face) Glyph(dot fixed.Point26_6, r rune) (
|
|||
return newDot, dr, a.mask, image.Point{}, true
|
||||
}
|
||||
|
||||
func (a *face) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool) {
|
||||
if err := a.glyphBuf.Load(a.f, a.scale, a.f.Index(r), a.hinting); err != nil {
|
||||
return fixed.Rectangle26_6{}, 0, false
|
||||
}
|
||||
xmin := +a.glyphBuf.B.XMin
|
||||
ymin := -a.glyphBuf.B.YMax
|
||||
xmax := +a.glyphBuf.B.XMax
|
||||
ymax := -a.glyphBuf.B.YMin
|
||||
if xmin > xmax || ymin > ymax {
|
||||
return fixed.Rectangle26_6{}, 0, false
|
||||
}
|
||||
return fixed.Rectangle26_6{
|
||||
Min: fixed.Point26_6{
|
||||
X: xmin,
|
||||
Y: ymin,
|
||||
},
|
||||
Max: fixed.Point26_6{
|
||||
X: xmax,
|
||||
Y: ymax,
|
||||
},
|
||||
}, a.glyphBuf.AdvanceWidth, true
|
||||
}
|
||||
|
||||
func (a *face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) {
|
||||
if err := a.glyphBuf.Load(a.f, a.scale, a.f.Index(r), a.hinting); err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return a.glyphBuf.AdvanceWidth, true
|
||||
}
|
||||
|
||||
// rasterize returns the advance width, integer-pixel offset to render at, and
|
||||
// the width and height of the given glyph at the given sub-pixel offsets.
|
||||
//
|
||||
|
@ -143,10 +173,10 @@ func (a *face) rasterize(index Index, fx, fy fixed.Int26_6) (
|
|||
return 0, image.Point{}, 0, 0, false
|
||||
}
|
||||
// Calculate the integer-pixel bounds for the glyph.
|
||||
xmin := int(fx+fixed.Int26_6(a.glyphBuf.B.XMin)) >> 6
|
||||
ymin := int(fy-fixed.Int26_6(a.glyphBuf.B.YMax)) >> 6
|
||||
xmax := int(fx+fixed.Int26_6(a.glyphBuf.B.XMax)+0x3f) >> 6
|
||||
ymax := int(fy-fixed.Int26_6(a.glyphBuf.B.YMin)+0x3f) >> 6
|
||||
xmin := int(fx+a.glyphBuf.B.XMin) >> 6
|
||||
ymin := int(fy-a.glyphBuf.B.YMax) >> 6
|
||||
xmax := int(fx+a.glyphBuf.B.XMax+0x3f) >> 6
|
||||
ymax := int(fy-a.glyphBuf.B.YMin+0x3f) >> 6
|
||||
if xmin > xmax || ymin > ymax {
|
||||
return 0, image.Point{}, 0, 0, false
|
||||
}
|
||||
|
@ -155,8 +185,8 @@ func (a *face) rasterize(index Index, fx, fy fixed.Int26_6) (
|
|||
// the pixel offsets, based on the font's FUnit metrics, that let a
|
||||
// negative co-ordinate in TrueType space be non-negative in rasterizer
|
||||
// space. xmin and ymin are typically <= 0.
|
||||
fx += fixed.Int26_6(-xmin << 6)
|
||||
fy += fixed.Int26_6(-ymin << 6)
|
||||
fx -= fixed.Int26_6(xmin << 6)
|
||||
fy -= fixed.Int26_6(ymin << 6)
|
||||
// Rasterize the glyph's vectors.
|
||||
a.r.Clear()
|
||||
clear(a.mask.Pix)
|
||||
|
@ -166,7 +196,7 @@ func (a *face) rasterize(index Index, fx, fy fixed.Int26_6) (
|
|||
e0 = e1
|
||||
}
|
||||
a.r.Rasterize(a.p)
|
||||
return fixed.Int26_6(a.glyphBuf.AdvanceWidth), image.Point{xmin, ymin}, xmax-xmin, ymax-ymin, true
|
||||
return a.glyphBuf.AdvanceWidth, image.Point{xmin, ymin}, xmax - xmin, ymax - ymin, true
|
||||
}
|
||||
|
||||
func clear(pix []byte) {
|
||||
|
|
Loading…
Reference in a new issue