提交 24265d1c 编写于 作者: N Nigel Tao

Implement GlyphBounds and GlyphAdvance.

上级 9c46b875
...@@ -37,6 +37,8 @@ var ( ...@@ -37,6 +37,8 @@ var (
wonb = flag.Bool("whiteonblack", false, "white text on a black background") wonb = flag.Bool("whiteonblack", false, "white text on a black background")
) )
const title = "Jabberwocky"
var text = []string{ var text = []string{
"’Twas brillig, and the slithy toves", "’Twas brillig, and the slithy toves",
"Did gyre and gimble in the wabe;", "Did gyre and gimble in the wabe;",
...@@ -96,7 +98,8 @@ func main() { ...@@ -96,7 +98,8 @@ func main() {
fg, bg = image.White, image.Black fg, bg = image.White, image.Black
ruler = color.RGBA{0x22, 0x22, 0x22, 0xff} 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) draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src)
for i := 0; i < 200; i++ { for i := 0; i < 200; i++ {
rgba.Set(10, 10+i, ruler) rgba.Set(10, 10+i, ruler)
...@@ -118,11 +121,18 @@ func main() { ...@@ -118,11 +121,18 @@ func main() {
Hinting: h, 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)) dy := int(math.Ceil(*size * *spacing * *dpi / 72))
for i, s := range text { d.Dot = fixed.Point26_6{
d.Dot = fixed.P(10, 10+dy0+i*dy) 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) d.DrawString(s)
y += dy
} }
// Save that RGBA image to disk. // Save that RGBA image to disk.
......
...@@ -132,6 +132,36 @@ func (a *face) Glyph(dot fixed.Point26_6, r rune) ( ...@@ -132,6 +132,36 @@ func (a *face) Glyph(dot fixed.Point26_6, r rune) (
return newDot, dr, a.mask, image.Point{}, true 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 // 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. // 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) ( ...@@ -143,10 +173,10 @@ func (a *face) rasterize(index Index, fx, fy fixed.Int26_6) (
return 0, image.Point{}, 0, 0, false return 0, image.Point{}, 0, 0, false
} }
// Calculate the integer-pixel bounds for the glyph. // Calculate the integer-pixel bounds for the glyph.
xmin := int(fx+fixed.Int26_6(a.glyphBuf.B.XMin)) >> 6 xmin := int(fx+a.glyphBuf.B.XMin) >> 6
ymin := int(fy-fixed.Int26_6(a.glyphBuf.B.YMax)) >> 6 ymin := int(fy-a.glyphBuf.B.YMax) >> 6
xmax := int(fx+fixed.Int26_6(a.glyphBuf.B.XMax)+0x3f) >> 6 xmax := int(fx+a.glyphBuf.B.XMax+0x3f) >> 6
ymax := int(fy-fixed.Int26_6(a.glyphBuf.B.YMin)+0x3f) >> 6 ymax := int(fy-a.glyphBuf.B.YMin+0x3f) >> 6
if xmin > xmax || ymin > ymax { if xmin > xmax || ymin > ymax {
return 0, image.Point{}, 0, 0, false return 0, image.Point{}, 0, 0, false
} }
...@@ -155,8 +185,8 @@ func (a *face) rasterize(index Index, fx, fy fixed.Int26_6) ( ...@@ -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 // the pixel offsets, based on the font's FUnit metrics, that let a
// negative co-ordinate in TrueType space be non-negative in rasterizer // negative co-ordinate in TrueType space be non-negative in rasterizer
// space. xmin and ymin are typically <= 0. // space. xmin and ymin are typically <= 0.
fx += fixed.Int26_6(-xmin << 6) fx -= fixed.Int26_6(xmin << 6)
fy += fixed.Int26_6(-ymin << 6) fy -= fixed.Int26_6(ymin << 6)
// Rasterize the glyph's vectors. // Rasterize the glyph's vectors.
a.r.Clear() a.r.Clear()
clear(a.mask.Pix) clear(a.mask.Pix)
...@@ -166,7 +196,7 @@ func (a *face) rasterize(index Index, fx, fy fixed.Int26_6) ( ...@@ -166,7 +196,7 @@ func (a *face) rasterize(index Index, fx, fy fixed.Int26_6) (
e0 = e1 e0 = e1
} }
a.r.Rasterize(a.p) 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) { func clear(pix []byte) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册