func drawGlyphOver(dst *image.RGBA, r image.Rectangle, src *image.ColorImage, mask *image.Alpha, mp image.Point) { i0 := (r.Min.Y-dst.Rect.Min.Y)*dst.Stride + r.Min.X - dst.Rect.Min.X i1 := i0 + r.Dx() j0 := (mp.Y-mask.Rect.Min.Y)*mask.Stride + mp.X - mask.Rect.Min.X cr, cg, cb, ca := src.RGBA() for y, my := r.Min.Y, mp.Y; y != r.Max.Y; y, my = y+1, my+1 { dpix := dst.Pix[i0:i1] mpix := mask.Pix[j0:] for i, rgba := range dpix { ma := uint32(mpix[i].A) if ma == 0 { continue } ma |= ma << 8 dr := uint32(rgba.R) dg := uint32(rgba.G) db := uint32(rgba.B) da := uint32(rgba.A) // The 0x101 is here for the same reason as in drawRGBA. a := (m - (ca * ma / m)) * 0x101 dr = (dr*a + cr*ma) / m dg = (dg*a + cg*ma) / m db = (db*a + cb*ma) / m da = (da*a + ca*ma) / m dpix[i] = image.RGBAColor{uint8(dr >> 8), uint8(dg >> 8), uint8(db >> 8), uint8(da >> 8)} } i0 += dst.Stride i1 += dst.Stride j0 += mask.Stride } }
func drawGlyphOver(dst *image.RGBA, r image.Rectangle, src *image.ColorImage, mask *image.Alpha, mp image.Point) { i0 := (r.Min.Y-dst.Rect.Min.Y)*dst.Stride + (r.Min.X-dst.Rect.Min.X)*4 i1 := i0 + r.Dx()*4 mi0 := (mp.Y-mask.Rect.Min.Y)*mask.Stride + mp.X - mask.Rect.Min.X 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 drawGlyphOver(dst *image.RGBA, r image.Rectangle, src *image.ColorImage, mask *image.Alpha, mp image.Point) { x0, x1 := r.Min.X, r.Max.X y0, y1 := r.Min.Y, r.Max.Y cr, cg, cb, ca := src.RGBA() for y, my := y0, mp.Y; y != y1; y, my = y+1, my+1 { dbase := y * dst.Stride dpix := dst.Pix[dbase+x0 : dbase+x1] mbase := my * mask.Stride mpix := mask.Pix[mbase+mp.X:] for i, rgba := range dpix { ma := uint32(mpix[i].A) if ma == 0 { continue } ma |= ma << 8 dr := uint32(rgba.R) dg := uint32(rgba.G) db := uint32(rgba.B) da := uint32(rgba.A) // The 0x101 is here for the same reason as in drawRGBA. a := (m - (ca * ma / m)) * 0x101 dr = (dr*a + cr*ma) / m dg = (dg*a + cg*ma) / m db = (db*a + cb*ma) / m da = (da*a + ca*ma) / m dpix[i] = image.RGBAColor{uint8(dr >> 8), uint8(dg >> 8), uint8(db >> 8), uint8(da >> 8)} } } }
func drawFillOver(dst *image.RGBA, r image.Rectangle, src *image.ColorImage) { cr, cg, cb, ca := src.RGBA() // The 0x101 is here for the same reason as in drawRGBA. a := (m - ca) * 0x101 x0, x1 := r.Min.X, r.Max.X y0, y1 := r.Min.Y, r.Max.Y for y := y0; y != y1; y++ { dbase := y * dst.Stride dpix := dst.Pix[dbase+x0 : dbase+x1] for i, rgba := range dpix { dr := (uint32(rgba.R)*a)/m + cr dg := (uint32(rgba.G)*a)/m + cg db := (uint32(rgba.B)*a)/m + cb da := (uint32(rgba.A)*a)/m + ca dpix[i] = image.RGBAColor{uint8(dr >> 8), uint8(dg >> 8), uint8(db >> 8), uint8(da >> 8)} } } }
func drawFillOver(dst *image.RGBA, r image.Rectangle, src *image.ColorImage) { cr, cg, cb, ca := src.RGBA() // The 0x101 is here for the same reason as in drawRGBA. a := (m - ca) * 0x101 i0 := (r.Min.Y-dst.Rect.Min.Y)*dst.Stride + r.Min.X - dst.Rect.Min.X i1 := i0 + r.Dx() for y := r.Min.Y; y != r.Max.Y; y++ { dpix := dst.Pix[i0:i1] for i, rgba := range dpix { dr := (uint32(rgba.R)*a)/m + cr dg := (uint32(rgba.G)*a)/m + cg db := (uint32(rgba.B)*a)/m + cb da := (uint32(rgba.A)*a)/m + ca dpix[i] = image.RGBAColor{uint8(dr >> 8), uint8(dg >> 8), uint8(db >> 8), uint8(da >> 8)} } i0 += dst.Stride i1 += dst.Stride } }
func drawFillSrc(dst *image.RGBA, r image.Rectangle, src *image.ColorImage) { sr, sg, sb, sa := src.RGBA() // The built-in copy function is faster than a straightforward for loop to fill the destination with // the color, but copy requires a slice source. We therefore use a for loop to fill the first row, and // then use the first row as the slice source for the remaining rows. i0 := (r.Min.Y-dst.Rect.Min.Y)*dst.Stride + (r.Min.X-dst.Rect.Min.X)*4 i1 := i0 + r.Dx()*4 for i := i0; i < i1; i += 4 { dst.Pix[i+0] = uint8(sr >> 8) dst.Pix[i+1] = uint8(sg >> 8) dst.Pix[i+2] = uint8(sb >> 8) dst.Pix[i+3] = uint8(sa >> 8) } firstRow := dst.Pix[i0:i1] for y := r.Min.Y + 1; y < r.Max.Y; y++ { i0 += dst.Stride i1 += dst.Stride copy(dst.Pix[i0:i1], firstRow) } }
func drawFill(dst *image.RGBA, r Rectangle, src image.ColorImage) { if r.Dy() < 1 { return } cr, cg, cb, ca := src.RGBA() color := image.RGBAColor{uint8(cr >> 24), uint8(cg >> 24), uint8(cb >> 24), uint8(ca >> 24)} // The built-in copy function is faster than a straightforward for loop to fill the destination with // the color, but copy requires a slice source. We therefore use a for loop to fill the first row, and // then use the first row as the slice source for the remaining rows. dx0, dx1 := r.Min.X, r.Max.X dy0, dy1 := r.Min.Y, r.Max.Y firstRow := dst.Pixel[dy0] for x := dx0; x < dx1; x++ { firstRow[x] = color } copySrc := firstRow[dx0:dx1] for y := dy0 + 1; y < dy1; y++ { copy(dst.Pixel[y][dx0:dx1], copySrc) } }
func drawFillSrc(dst *image.RGBA, r image.Rectangle, src *image.ColorImage) { if r.Dy() < 1 { return } cr, cg, cb, ca := src.RGBA() color := image.RGBAColor{uint8(cr >> 8), uint8(cg >> 8), uint8(cb >> 8), uint8(ca >> 8)} // The built-in copy function is faster than a straightforward for loop to fill the destination with // the color, but copy requires a slice source. We therefore use a for loop to fill the first row, and // then use the first row as the slice source for the remaining rows. i0 := (r.Min.Y-dst.Rect.Min.Y)*dst.Stride + r.Min.X - dst.Rect.Min.X i1 := i0 + r.Dx() firstRow := dst.Pix[i0:i1] for i := range firstRow { firstRow[i] = color } for y := r.Min.Y + 1; y < r.Max.Y; y++ { i0 += dst.Stride i1 += dst.Stride copy(dst.Pix[i0:i1], firstRow) } }
func drawFillOver(dst *image.RGBA, r image.Rectangle, src *image.ColorImage) { sr, sg, sb, sa := src.RGBA() // The 0x101 is here for the same reason as in drawRGBA. a := (m - sa) * 0x101 i0 := (r.Min.Y-dst.Rect.Min.Y)*dst.Stride + (r.Min.X-dst.Rect.Min.X)*4 i1 := i0 + r.Dx()*4 for y := r.Min.Y; y != r.Max.Y; y++ { for i := i0; i < i1; i += 4 { dr := uint32(dst.Pix[i+0]) dg := uint32(dst.Pix[i+1]) db := uint32(dst.Pix[i+2]) da := uint32(dst.Pix[i+3]) dst.Pix[i+0] = uint8((dr*a/m + sr) >> 8) dst.Pix[i+1] = uint8((dg*a/m + sg) >> 8) dst.Pix[i+2] = uint8((db*a/m + sb) >> 8) dst.Pix[i+3] = uint8((da*a/m + sa) >> 8) } i0 += dst.Stride i1 += dst.Stride } }