Пример #1
0
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
	}
}
Пример #2
0
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)
		}
	}
}
Пример #3
0
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
	}
}
Пример #4
0
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)}
}
Пример #5
0
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)
	}
}