Freetype-Go: gamma is now a float instead of a float64.
R=r CC=golang-dev http://codereview.appspot.com/1236042
This commit is contained in:
parent
25c38cfec1
commit
9c4da76964
4 changed files with 50 additions and 30 deletions
|
@ -16,6 +16,7 @@ import (
|
|||
var (
|
||||
dpi = flag.Int("dpi", 72, "screen resolution in Dots Per Inch")
|
||||
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")
|
||||
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")
|
||||
|
@ -87,6 +88,7 @@ func main() {
|
|||
c.SetDPI(*dpi)
|
||||
c.SetFont(font)
|
||||
c.SetFontSize(*size)
|
||||
c.SetGamma(*gamma)
|
||||
|
||||
// Draw the guidelines.
|
||||
for i := 0; i < 200; i++ {
|
||||
|
|
|
@ -53,7 +53,7 @@ func main() {
|
|||
mask := image.NewAlpha(50, 50)
|
||||
painter := raster.NewAlphaPainter(mask)
|
||||
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 {
|
||||
clear(mask)
|
||||
r.Rasterize(raster.NewGammaCorrectionPainter(painter, g))
|
||||
|
|
|
@ -32,7 +32,8 @@ func Pt(x, y int) raster.Point {
|
|||
// given size.
|
||||
type RGBAContext struct {
|
||||
r *raster.Rasterizer
|
||||
p *raster.RGBAPainter
|
||||
rp *raster.RGBAPainter
|
||||
gp *raster.GammaCorrectionPainter
|
||||
font *truetype.Font
|
||||
glyphBuf *truetype.GlyphBuf
|
||||
fontSize float
|
||||
|
@ -144,7 +145,7 @@ func (c *RGBAContext) DrawText(pt raster.Point, s string) (err os.Error) {
|
|||
advance, x0 := 0, pt.X
|
||||
dx := raster.Fixed(-c.xmin << 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
|
||||
prev, hasPrev := truetype.Index(0), false
|
||||
for _, ch := range s {
|
||||
|
@ -169,7 +170,7 @@ func (c *RGBAContext) DrawText(pt raster.Point, s string) (err os.Error) {
|
|||
x = x0 + c.FUnitToFixed(advance)
|
||||
// Break the co-ordinate down into an integer pixel part and a
|
||||
// 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
|
||||
// Draw the contours.
|
||||
c.r.Clear()
|
||||
|
@ -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)
|
||||
e0 = e
|
||||
}
|
||||
c.r.Rasterize(c.p)
|
||||
c.r.Rasterize(c.gp)
|
||||
// Advance the cursor.
|
||||
advance += int(c.font.HMetric(index).AdvanceWidth)
|
||||
prev, hasPrev = index, true
|
||||
|
@ -204,7 +205,7 @@ func (c *RGBAContext) recalc() {
|
|||
|
||||
// SetColor sets the color to draw text.
|
||||
func (c *RGBAContext) SetColor(color image.Color) {
|
||||
c.p.SetColor(color)
|
||||
c.rp.SetColor(color)
|
||||
}
|
||||
|
||||
// SetDPI sets the screen resolution in dots per inch.
|
||||
|
@ -229,20 +230,27 @@ func (c *RGBAContext) SetFontSize(fontSize float) {
|
|||
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.
|
||||
func (c *RGBAContext) SetRGBA(m *image.RGBA) {
|
||||
c.p.Image = m
|
||||
c.rp.Image = m
|
||||
}
|
||||
|
||||
// NewRGBAContext creates a new RGBAContext.
|
||||
func NewRGBAContext(m *image.RGBA) *RGBAContext {
|
||||
return &RGBAContext{
|
||||
c := &RGBAContext{
|
||||
r: raster.NewRasterizer(0, 0),
|
||||
p: raster.NewRGBAPainter(m),
|
||||
rp: raster.NewRGBAPainter(m),
|
||||
glyphBuf: truetype.NewGlyphBuf(),
|
||||
fontSize: 12,
|
||||
dpi: 72,
|
||||
upe: 2048,
|
||||
scale: (12 * 72 * 256 * 256) / (2048 * 72),
|
||||
}
|
||||
c.gp = raster.NewGammaCorrectionPainter(c.rp, 1.0)
|
||||
return c
|
||||
}
|
||||
|
|
|
@ -215,46 +215,56 @@ type GammaCorrectionPainter struct {
|
|||
Painter Painter
|
||||
// Precomputed alpha values for linear interpolation, with fully opaque == 1<<16-1.
|
||||
a [256]uint16
|
||||
// Whether gamma correction is a no-op.
|
||||
gammaIsOne bool
|
||||
}
|
||||
|
||||
// Paint delegates to the wrapped Painter after performing gamma-correction
|
||||
// on each Span.
|
||||
func (g *GammaCorrectionPainter) Paint(ss []Span) {
|
||||
const (
|
||||
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 {
|
||||
continue
|
||||
if !g.gammaIsOne {
|
||||
const (
|
||||
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 {
|
||||
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].
|
||||
a := uint32(g.a[p])*(N-q) + uint32(g.a[p+1])*q
|
||||
a = (a + N/2) / N
|
||||
// Convert the alpha from 16-bit (which is g.a's range) to 32-bit.
|
||||
a |= a << 16
|
||||
// A non-final Span can't have zero alpha.
|
||||
if a == 0 {
|
||||
a = 1
|
||||
}
|
||||
ss[i].A = a
|
||||
}
|
||||
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].
|
||||
a := uint32(g.a[p])*(N-q) + uint32(g.a[p+1])*q
|
||||
a = (a + N/2) / N
|
||||
// Convert the alpha from 16-bit (which is g.a's range) to 32-bit.
|
||||
a |= a << 16
|
||||
// A non-final Span can't have zero alpha.
|
||||
if a == 0 {
|
||||
a = 1
|
||||
}
|
||||
ss[i].A = a
|
||||
}
|
||||
g.Painter.Paint(ss)
|
||||
}
|
||||
|
||||
// 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++ {
|
||||
a := float64(i) / 0xff
|
||||
a = math.Pow(a, gamma)
|
||||
a = math.Pow(a, gamma64)
|
||||
g.a[i] = uint16(0xffff * a)
|
||||
}
|
||||
}
|
||||
|
||||
// NewGammaCorrectionPainter creates a new GammaCorrectionPainter that wraps
|
||||
// the given Painter.
|
||||
func NewGammaCorrectionPainter(p Painter, gamma float64) *GammaCorrectionPainter {
|
||||
func NewGammaCorrectionPainter(p Painter, gamma float) *GammaCorrectionPainter {
|
||||
g := &GammaCorrectionPainter{Painter: p}
|
||||
g.SetGamma(gamma)
|
||||
return g
|
||||
|
|
Loading…
Reference in a new issue