// Copyright 2010 The Freetype-Go Authors. All rights reserved.// Use of this source code is governed by your choice of either the// FreeType License or the GNU General Public License version 2 (or// any later version), both of which can be found in the LICENSE file.package rasterimport ()// A Span is a horizontal segment of pixels with constant alpha. X0 is an// inclusive bound and X1 is exclusive, the same as for slices. A fully opaque// Span has Alpha == 0xffff.typeSpanstruct { Y, X0, X1 int Alpha uint32}// A Painter knows how to paint a batch of Spans. Rasterization may involve// Painting multiple batches, and done will be true for the final batch. The// Spans' Y values are monotonically increasing during a rasterization. Paint// may use all of ss as scratch space during the call.typePainterinterface {Paint(ss []Span, done bool)}// The PainterFunc type adapts an ordinary function to the Painter interface.typePainterFuncfunc(ss []Span, done bool)// Paint just delegates the call to f.func ( PainterFunc) ( []Span, bool) { (, ) }// An AlphaOverPainter is a Painter that paints Spans onto a *image.Alpha using// the Over Porter-Duff composition operator.typeAlphaOverPainterstruct { Image *image.Alpha}// Paint satisfies the Painter interface.func ( AlphaOverPainter) ( []Span, bool) { := .Image.Bounds()for , := range {if .Y < .Min.Y {continue }if .Y >= .Max.Y {return }if .X0 < .Min.X { .X0 = .Min.X }if .X1 > .Max.X { .X1 = .Max.X }if .X0 >= .X1 {continue } := (.Y-.Image.Rect.Min.Y)*.Image.Stride - .Image.Rect.Min.X := .Image.Pix[+.X0 : +.X1] := int(.Alpha >> 8)for , := range { := int() [] = uint8((*255 + (255-)*) / 255) } }}// NewAlphaOverPainter creates a new AlphaOverPainter for the given image.func ( *image.Alpha) AlphaOverPainter {returnAlphaOverPainter{}}// An AlphaSrcPainter is a Painter that paints Spans onto a *image.Alpha using// the Src Porter-Duff composition operator.typeAlphaSrcPainterstruct { Image *image.Alpha}// Paint satisfies the Painter interface.func ( AlphaSrcPainter) ( []Span, bool) { := .Image.Bounds()for , := range {if .Y < .Min.Y {continue }if .Y >= .Max.Y {return }if .X0 < .Min.X { .X0 = .Min.X }if .X1 > .Max.X { .X1 = .Max.X }if .X0 >= .X1 {continue } := (.Y-.Image.Rect.Min.Y)*.Image.Stride - .Image.Rect.Min.X := .Image.Pix[+.X0 : +.X1] := uint8(.Alpha >> 8)for := range { [] = } }}// NewAlphaSrcPainter creates a new AlphaSrcPainter for the given image.func ( *image.Alpha) AlphaSrcPainter {returnAlphaSrcPainter{}}// An RGBAPainter is a Painter that paints Spans onto a *image.RGBA.typeRGBAPainterstruct {// Image is the image to compose onto. Image *image.RGBA// Op is the Porter-Duff composition operator. Op draw.Op// cr, cg, cb and ca are the 16-bit color to paint the spans. cr, cg, cb, ca uint32}// Paint satisfies the Painter interface.func ( *RGBAPainter) ( []Span, bool) { := .Image.Bounds()for , := range {if .Y < .Min.Y {continue }if .Y >= .Max.Y {return }if .X0 < .Min.X { .X0 = .Min.X }if .X1 > .Max.X { .X1 = .Max.X }if .X0 >= .X1 {continue }// This code mimics drawGlyphOver in $GOROOT/src/image/draw/draw.go. := .Alphaconst = 1<<16 - 1 := (.Y-.Image.Rect.Min.Y)*.Image.Stride + (.X0-.Image.Rect.Min.X)*4 := + (.X1-.X0)*4if .Op == draw.Over {for := ; < ; += 4 { := uint32(.Image.Pix[+0]) := uint32(.Image.Pix[+1]) := uint32(.Image.Pix[+2]) := uint32(.Image.Pix[+3]) := ( - (.ca * / )) * 0x101 .Image.Pix[+0] = uint8((* + .cr*) / >> 8) .Image.Pix[+1] = uint8((* + .cg*) / >> 8) .Image.Pix[+2] = uint8((* + .cb*) / >> 8) .Image.Pix[+3] = uint8((* + .ca*) / >> 8) } } else {for := ; < ; += 4 { .Image.Pix[+0] = uint8(.cr * / >> 8) .Image.Pix[+1] = uint8(.cg * / >> 8) .Image.Pix[+2] = uint8(.cb * / >> 8) .Image.Pix[+3] = uint8(.ca * / >> 8) } } }}// SetColor sets the color to paint the spans.func ( *RGBAPainter) ( color.Color) { .cr, .cg, .cb, .ca = .RGBA()}// NewRGBAPainter creates a new RGBAPainter for the given image.func ( *image.RGBA) *RGBAPainter {return &RGBAPainter{Image: }}// A MonochromePainter wraps another Painter, quantizing each Span's alpha to// be either fully opaque or fully transparent.typeMonochromePainterstruct { Painter Painter y, x0, x1 int}// Paint delegates to the wrapped Painter after quantizing each Span's alpha// value and merging adjacent fully opaque Spans.func ( *MonochromePainter) ( []Span, bool) {// We compact the ss slice, discarding any Spans whose alpha quantizes to zero. := 0for , := range {if .Alpha >= 0x8000 {if .y == .Y && .x1 == .X0 { .x1 = .X1 } else { [] = Span{.y, .x0, .x1, 1<<16 - 1} ++ .y, .x0, .x1 = .Y, .X0, .X1 } } }if {// Flush the accumulated Span. := Span{.y, .x0, .x1, 1<<16 - 1}if < len() { [] = ++ .Painter.Paint([:], true) } elseif == len() { .Painter.Paint(, false)ifcap() > 0 { = [:1] } else { = make([]Span, 1) } [0] = .Painter.Paint(, true) } else {panic("unreachable") }// Reset the accumulator, so that this Painter can be re-used. .y, .x0, .x1 = 0, 0, 0 } else { .Painter.Paint([:], false) }}// NewMonochromePainter creates a new MonochromePainter that wraps the given// Painter.func ( Painter) *MonochromePainter {return &MonochromePainter{Painter: }}// A GammaCorrectionPainter wraps another Painter, performing gamma-correction// on each Span's alpha value.typeGammaCorrectionPainterstruct {// Painter is the wrapped Painter. Painter Painter// a is the precomputed alpha values for linear interpolation, with fully // opaque == 0xffff. a [256]uint16// gammaIsOne is whether gamma correction is a no-op. gammaIsOne bool}// Paint delegates to the wrapped Painter after performing gamma-correction on// each Span.func ( *GammaCorrectionPainter) ( []Span, bool) {if !.gammaIsOne {const = 0x101for , := range {if .Alpha == 0 || .Alpha == 0xffff {continue } , := .Alpha/, .Alpha%// The resultant alpha is a linear interpolation of g.a[p] and g.a[p+1]. := uint32(.a[])*(-) + uint32(.a[+1])* [].Alpha = ( + /2) / } } .Painter.Paint(, )}// SetGamma sets the gamma value.func ( *GammaCorrectionPainter) ( float64) { .gammaIsOne = == 1if .gammaIsOne {return }for := 0; < 256; ++ { := float64() / 0xff = math.Pow(, ) .a[] = uint16(0xffff * ) }}// NewGammaCorrectionPainter creates a new GammaCorrectionPainter that wraps// the given Painter.func ( Painter, float64) *GammaCorrectionPainter { := &GammaCorrectionPainter{Painter: } .SetGamma()return}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.