Use premultiplied alpha for X canvas
This commit is contained in:
@@ -132,3 +132,32 @@ func convertColor (c color.Color) xgraphics.BGRA {
|
||||
A: uint8(a >> 8),
|
||||
}
|
||||
}
|
||||
|
||||
// For some reason, xgraphics.BGRA does not specify whether or not it uses
|
||||
// premultiplied alpha, and information regarding this is contradictory.
|
||||
// Basically:
|
||||
// - BGRAModel just takes the result of c.RGBA and bit shifts it, without
|
||||
// un-doing the aplha premultiplication that is required by Color.RGBA,
|
||||
// suggesting that xgraphics.BGRA stores alpha-premultiplied color.
|
||||
// - xgraphics.BlendBGRA lerps between dest and src using only the alpha of
|
||||
// src (temporarily converting the colors to fucking floats for some reason)
|
||||
// which seems to suggest that xgraphics.BGRA *does not* store alpha-
|
||||
// premultiplied color.
|
||||
// There is no issues page on xgbutil so we may never get an answer to this
|
||||
// question. However, in this package we just use xgraphics.BGRA to store alpha-
|
||||
// premultiplied color anyway because its way faster, and I would sooner eat
|
||||
// spaghetti with a spoon than convert to and from float64 to blend pixels.
|
||||
func blendPremultipliedBGRA (dst, src xgraphics.BGRA) xgraphics.BGRA {
|
||||
// https://en.wikipedia.org/wiki/Alpha_compositing
|
||||
return xgraphics.BGRA {
|
||||
B: blendPremultipliedChannel(dst.B, src.B, src.A),
|
||||
G: blendPremultipliedChannel(dst.G, src.G, src.A),
|
||||
R: blendPremultipliedChannel(dst.R, src.R, src.A),
|
||||
A: blendPremultipliedChannel(dst.A, src.A, src.A),
|
||||
}
|
||||
}
|
||||
|
||||
func blendPremultipliedChannel (dst, src, a uint8) uint8 {
|
||||
dst16, src16, a16 := uint16(dst), uint16(src), uint16(a)
|
||||
return uint8(src16 + ((dst16 * (255 - a16)) >> 8))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user