提交 9c4da769 编写于 作者: N Nigel Tao

Freetype-Go: gamma is now a float instead of a float64.

R=r
CC=golang-dev
http://codereview.appspot.com/1236042
上级 25c38cfe
...@@ -16,6 +16,7 @@ import ( ...@@ -16,6 +16,7 @@ import (
var ( var (
dpi = flag.Int("dpi", 72, "screen resolution in Dots Per Inch") dpi = flag.Int("dpi", 72, "screen resolution in Dots Per Inch")
fontfile = flag.String("fontfile", "../../luxi-fonts/luxisr.ttf", "filename of the ttf font") fontfile = flag.String("fontfile", "../../luxi-fonts/luxisr.ttf", "filename of the ttf font")
gamma = flag.Float("gamma", 1.0, "gamma correction")
size = flag.Float("size", 12, "font size in points") size = flag.Float("size", 12, "font size in points")
spacing = flag.Float("spacing", 1.5, "line spacing (e.g. 2 means double spaced)") spacing = flag.Float("spacing", 1.5, "line spacing (e.g. 2 means double spaced)")
wonb = flag.Bool("whiteonblack", false, "white text on a black background") wonb = flag.Bool("whiteonblack", false, "white text on a black background")
...@@ -87,6 +88,7 @@ func main() { ...@@ -87,6 +88,7 @@ func main() {
c.SetDPI(*dpi) c.SetDPI(*dpi)
c.SetFont(font) c.SetFont(font)
c.SetFontSize(*size) c.SetFontSize(*size)
c.SetGamma(*gamma)
// Draw the guidelines. // Draw the guidelines.
for i := 0; i < 200; i++ { for i := 0; i < 200; i++ {
......
...@@ -53,7 +53,7 @@ func main() { ...@@ -53,7 +53,7 @@ func main() {
mask := image.NewAlpha(50, 50) mask := image.NewAlpha(50, 50)
painter := raster.NewAlphaPainter(mask) painter := raster.NewAlphaPainter(mask)
painter.Op = draw.Src painter.Op = draw.Src
gammas := []float64{1.0 / 10.0, 1.0 / 3.0, 1.0 / 2.0, 2.0 / 3.0, 4.0 / 5.0, 1.0, 5.0 / 4.0, 3.0 / 2.0, 2.0, 3.0, 10.0} gammas := []float{1.0 / 10.0, 1.0 / 3.0, 1.0 / 2.0, 2.0 / 3.0, 4.0 / 5.0, 1.0, 5.0 / 4.0, 3.0 / 2.0, 2.0, 3.0, 10.0}
for i, g := range gammas { for i, g := range gammas {
clear(mask) clear(mask)
r.Rasterize(raster.NewGammaCorrectionPainter(painter, g)) r.Rasterize(raster.NewGammaCorrectionPainter(painter, g))
......
...@@ -32,7 +32,8 @@ func Pt(x, y int) raster.Point { ...@@ -32,7 +32,8 @@ func Pt(x, y int) raster.Point {
// given size. // given size.
type RGBAContext struct { type RGBAContext struct {
r *raster.Rasterizer r *raster.Rasterizer
p *raster.RGBAPainter rp *raster.RGBAPainter
gp *raster.GammaCorrectionPainter
font *truetype.Font font *truetype.Font
glyphBuf *truetype.GlyphBuf glyphBuf *truetype.GlyphBuf
fontSize float fontSize float
...@@ -144,7 +145,7 @@ func (c *RGBAContext) DrawText(pt raster.Point, s string) (err os.Error) { ...@@ -144,7 +145,7 @@ func (c *RGBAContext) DrawText(pt raster.Point, s string) (err os.Error) {
advance, x0 := 0, pt.X advance, x0 := 0, pt.X
dx := raster.Fixed(-c.xmin << 8) dx := raster.Fixed(-c.xmin << 8)
dy := raster.Fixed(-c.ymin << 8) dy := raster.Fixed(-c.ymin << 8)
c.p.Dy, y = c.ymin+int(pt.Y>>8), pt.Y&0xff c.rp.Dy, y = c.ymin+int(pt.Y>>8), pt.Y&0xff
y += dy y += dy
prev, hasPrev := truetype.Index(0), false prev, hasPrev := truetype.Index(0), false
for _, ch := range s { for _, ch := range s {
...@@ -169,7 +170,7 @@ func (c *RGBAContext) DrawText(pt raster.Point, s string) (err os.Error) { ...@@ -169,7 +170,7 @@ func (c *RGBAContext) DrawText(pt raster.Point, s string) (err os.Error) {
x = x0 + c.FUnitToFixed(advance) x = x0 + c.FUnitToFixed(advance)
// Break the co-ordinate down into an integer pixel part and a // Break the co-ordinate down into an integer pixel part and a
// sub-pixel part, making sure that the latter is non-negative. // sub-pixel part, making sure that the latter is non-negative.
c.p.Dx, x = c.xmin+int(x>>8), x&0xff c.rp.Dx, x = c.xmin+int(x>>8), x&0xff
x += dx x += dx
// Draw the contours. // Draw the contours.
c.r.Clear() c.r.Clear()
...@@ -178,7 +179,7 @@ func (c *RGBAContext) DrawText(pt raster.Point, s string) (err os.Error) { ...@@ -178,7 +179,7 @@ func (c *RGBAContext) DrawText(pt raster.Point, s string) (err os.Error) {
c.drawContour(c.glyphBuf.Point[e0:e], x, y) c.drawContour(c.glyphBuf.Point[e0:e], x, y)
e0 = e e0 = e
} }
c.r.Rasterize(c.p) c.r.Rasterize(c.gp)
// Advance the cursor. // Advance the cursor.
advance += int(c.font.HMetric(index).AdvanceWidth) advance += int(c.font.HMetric(index).AdvanceWidth)
prev, hasPrev = index, true prev, hasPrev = index, true
...@@ -204,7 +205,7 @@ func (c *RGBAContext) recalc() { ...@@ -204,7 +205,7 @@ func (c *RGBAContext) recalc() {
// SetColor sets the color to draw text. // SetColor sets the color to draw text.
func (c *RGBAContext) SetColor(color image.Color) { func (c *RGBAContext) SetColor(color image.Color) {
c.p.SetColor(color) c.rp.SetColor(color)
} }
// SetDPI sets the screen resolution in dots per inch. // SetDPI sets the screen resolution in dots per inch.
...@@ -229,20 +230,27 @@ func (c *RGBAContext) SetFontSize(fontSize float) { ...@@ -229,20 +230,27 @@ func (c *RGBAContext) SetFontSize(fontSize float) {
c.recalc() c.recalc()
} }
// SetGamma sets the gamma correction parameter.
func (c *RGBAContext) SetGamma(g float) {
c.gp.SetGamma(g)
}
// SetRGBA sets the image that the RGBAContext draws onto. // SetRGBA sets the image that the RGBAContext draws onto.
func (c *RGBAContext) SetRGBA(m *image.RGBA) { func (c *RGBAContext) SetRGBA(m *image.RGBA) {
c.p.Image = m c.rp.Image = m
} }
// NewRGBAContext creates a new RGBAContext. // NewRGBAContext creates a new RGBAContext.
func NewRGBAContext(m *image.RGBA) *RGBAContext { func NewRGBAContext(m *image.RGBA) *RGBAContext {
return &RGBAContext{ c := &RGBAContext{
r: raster.NewRasterizer(0, 0), r: raster.NewRasterizer(0, 0),
p: raster.NewRGBAPainter(m), rp: raster.NewRGBAPainter(m),
glyphBuf: truetype.NewGlyphBuf(), glyphBuf: truetype.NewGlyphBuf(),
fontSize: 12, fontSize: 12,
dpi: 72, dpi: 72,
upe: 2048, upe: 2048,
scale: (12 * 72 * 256 * 256) / (2048 * 72), scale: (12 * 72 * 256 * 256) / (2048 * 72),
} }
c.gp = raster.NewGammaCorrectionPainter(c.rp, 1.0)
return c
} }
...@@ -215,46 +215,56 @@ type GammaCorrectionPainter struct { ...@@ -215,46 +215,56 @@ type GammaCorrectionPainter struct {
Painter Painter Painter Painter
// Precomputed alpha values for linear interpolation, with fully opaque == 1<<16-1. // Precomputed alpha values for linear interpolation, with fully opaque == 1<<16-1.
a [256]uint16 a [256]uint16
// Whether gamma correction is a no-op.
gammaIsOne bool
} }
// Paint delegates to the wrapped Painter after performing gamma-correction // Paint delegates to the wrapped Painter after performing gamma-correction
// on each Span. // on each Span.
func (g *GammaCorrectionPainter) Paint(ss []Span) { func (g *GammaCorrectionPainter) Paint(ss []Span) {
const ( if !g.gammaIsOne {
M = 0x1010101 // 255*M == 1<<32-1 const (
N = 0x8080 // N = M>>9, and N < 1<<16-1 M = 0x1010101 // 255*M == 1<<32-1
) N = 0x8080 // N = M>>9, and N < 1<<16-1
for i, _ := range ss { )
if ss[i].A == 0 || ss[i].A == 1<<32-1 { for i, _ := range ss {
continue if ss[i].A == 0 || ss[i].A == 1<<32-1 {
} continue
p, q := ss[i].A/M, (ss[i].A%M)>>9 }
// The resultant alpha is a linear interpolation of g.a[p] and g.a[p+1]. p, q := ss[i].A/M, (ss[i].A%M)>>9
a := uint32(g.a[p])*(N-q) + uint32(g.a[p+1])*q // The resultant alpha is a linear interpolation of g.a[p] and g.a[p+1].
a = (a + N/2) / N a := uint32(g.a[p])*(N-q) + uint32(g.a[p+1])*q
// Convert the alpha from 16-bit (which is g.a's range) to 32-bit. a = (a + N/2) / N
a |= a << 16 // Convert the alpha from 16-bit (which is g.a's range) to 32-bit.
// A non-final Span can't have zero alpha. a |= a << 16
if a == 0 { // A non-final Span can't have zero alpha.
a = 1 if a == 0 {
a = 1
}
ss[i].A = a
} }
ss[i].A = a
} }
g.Painter.Paint(ss) g.Painter.Paint(ss)
} }
// SetGamma sets the gamma value. // SetGamma sets the gamma value.
func (g *GammaCorrectionPainter) SetGamma(gamma float64) { func (g *GammaCorrectionPainter) SetGamma(gamma float) {
if gamma == 1.0 {
g.gammaIsOne = true
return
}
g.gammaIsOne = false
gamma64 := float64(gamma)
for i := 0; i < 256; i++ { for i := 0; i < 256; i++ {
a := float64(i) / 0xff a := float64(i) / 0xff
a = math.Pow(a, gamma) a = math.Pow(a, gamma64)
g.a[i] = uint16(0xffff * a) g.a[i] = uint16(0xffff * a)
} }
} }
// NewGammaCorrectionPainter creates a new GammaCorrectionPainter that wraps // NewGammaCorrectionPainter creates a new GammaCorrectionPainter that wraps
// the given Painter. // the given Painter.
func NewGammaCorrectionPainter(p Painter, gamma float64) *GammaCorrectionPainter { func NewGammaCorrectionPainter(p Painter, gamma float) *GammaCorrectionPainter {
g := &GammaCorrectionPainter{Painter: p} g := &GammaCorrectionPainter{Painter: p}
g.SetGamma(gamma) g.SetGamma(gamma)
return g return g
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册