func drawGlyphOver(dst *image.RGBA, r image.Rectangle, src *image.Uniform, mask *image.Alpha, mp image.Point) { i0 := dst.PixOffset(r.Min.X, r.Min.Y) i1 := i0 + r.Dx()*4 mi0 := mask.PixOffset(mp.X, mp.Y) sr, sg, sb, sa := src.RGBA() for y, my := r.Min.Y, mp.Y; y != r.Max.Y; y, my = y+1, my+1 { for i, mi := i0, mi0; i < i1; i, mi = i+4, mi+1 { ma := uint32(mask.Pix[mi]) if ma == 0 { continue } ma |= ma << 8 dr := uint32(dst.Pix[i+0]) dg := uint32(dst.Pix[i+1]) db := uint32(dst.Pix[i+2]) da := uint32(dst.Pix[i+3]) // The 0x101 is here for the same reason as in drawRGBA. a := (m - (sa * ma / m)) * 0x101 dst.Pix[i+0] = uint8((dr*a + sr*ma) / m >> 8) dst.Pix[i+1] = uint8((dg*a + sg*ma) / m >> 8) dst.Pix[i+2] = uint8((db*a + sb*ma) / m >> 8) dst.Pix[i+3] = uint8((da*a + sa*ma) / m >> 8) } i0 += dst.Stride i1 += dst.Stride mi0 += mask.Stride } }
func (z *Rasterizer) rasterizeDstAlphaSrcOpaqueOpSrc(dst *image.Alpha, r image.Rectangle) { // TODO: non-zero vs even-odd winding? if r == dst.Bounds() && r == z.Bounds() { // We bypass the z.accumulateMask step and convert straight from // z.bufF32 or z.bufU32 to dst.Pix. if z.useFloatingPointMath { if haveFloatingAccumulateSIMD { floatingAccumulateOpSrcSIMD(dst.Pix, z.bufF32) } else { floatingAccumulateOpSrc(dst.Pix, z.bufF32) } } else { if haveFixedAccumulateSIMD { fixedAccumulateOpSrcSIMD(dst.Pix, z.bufU32) } else { fixedAccumulateOpSrc(dst.Pix, z.bufU32) } } return } z.accumulateMask() pix := dst.Pix[dst.PixOffset(r.Min.X, r.Min.Y):] for y, y1 := 0, r.Max.Y-r.Min.Y; y < y1; y++ { for x, x1 := 0, r.Max.X-r.Min.X; x < x1; x++ { ma := z.bufU32[y*z.size.X+x] // This formula is like rasterizeOpSrc's, simplified for the // concrete dst type and opaque src assumption. pix[y*dst.Stride+x] = uint8(ma >> 8) } } }
func newAtFuncAlpha(p *image.Alpha) AtFunc { return func(x, y int) (r, g, b, a uint32) { i := p.PixOffset(x, y) a = uint32(p.Pix[i]) a |= a << 8 return a, a, a, a } }
func bilinearAlpha(src *image.Alpha, x, y float32) color.Alpha { p := findLinearSrc(src.Bounds(), x, y) // Slice offsets for the surrounding pixels. off00 := src.PixOffset(p.low.X, p.low.Y) off01 := src.PixOffset(p.high.X, p.low.Y) off10 := src.PixOffset(p.low.X, p.high.Y) off11 := src.PixOffset(p.high.X, p.high.Y) fa := float32(src.Pix[off00]) * p.frac00 fa += float32(src.Pix[off01]) * p.frac01 fa += float32(src.Pix[off10]) * p.frac10 fa += float32(src.Pix[off11]) * p.frac11 return color.Alpha{A: uint8(fa + 0.5)} }
func newSetFuncAlpha(p *image.Alpha) SetFunc { return func(x, y int, r, g, b, a uint32) { i := p.PixOffset(x, y) p.Pix[i] = uint8(a >> 8) } }