diff options
author | bptato <nincsnevem662@gmail.com> | 2023-07-07 13:35:15 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2023-07-07 13:35:15 +0200 |
commit | b2514e94bac6f7b3462649834ad36287b0b29ab2 (patch) | |
tree | b1ecd39ba2b1227794e3edebfd4deb07332dd0d9 | |
parent | 01ce4740d41b1e00b1f9735f80a010f324b6f583 (diff) | |
download | chawan-b2514e94bac6f7b3462649834ad36287b0b29ab2.tar.gz |
Add separate type for premultiplied color
-rw-r--r-- | src/types/color.nim | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/src/types/color.nim b/src/types/color.nim index 70908508..d3526a43 100644 --- a/src/types/color.nim +++ b/src/types/color.nim @@ -7,8 +7,12 @@ import utils/twtstr type RGBColor* = distinct uint32 + # Straight RGBA color, stored in ARGB format RGBAColor* = distinct uint32 + # Premultiplied RGBA color + RGBAColorPremul* = distinct RGBAColor + ANSIColor* = distinct uint8 EightBitColor* = distinct uint8 @@ -239,6 +243,11 @@ proc `b=`*(c: var RGBAColor, b: uint8) = proc `a=`*(c: var RGBAColor, a: uint8) = c = RGBAColor(uint32(c) or (uint32(a) shl 24)) +func r*(c: RGBAColorPremul): uint8 {.borrow.} +func g*(c: RGBAColorPremul): uint8 {.borrow.} +func b*(c: RGBAColorPremul): uint8 {.borrow.} +func a*(c: RGBAColorPremul): uint8 {.borrow.} + # https://html.spec.whatwg.org/#serialisation-of-a-color func serialize*(color: RGBAColor): string = if color.a == 255: @@ -283,20 +292,17 @@ func fastmul1(c, ca: uint32): uint32 = ga = ga and 0xFF00FF00u32 return ga or (rb shr 8) -func fastmul(c: RGBAColor, ca: uint32): uint32 = - return fastmul(uint32(c), ca) - -func fastmul1(c: RGBAColor, ca: uint32): uint32 = - return fastmul1(uint32(c), ca) +func fastmul1(c: RGBAColorPremul, ca: uint32): RGBAColorPremul = + return RGBAColorPremul(fastmul1(uint32(c), ca)) func rgba*(r, g, b, a: uint8): RGBAColor -func premul(c: RGBAColor): RGBAColor = - return RGBAColor(fastmul(c, uint32(c.a))) +func premul(c: RGBAColor): RGBAColorPremul = + return RGBAColorPremul(fastmul(uint32(c), uint32(c.a))) # This is somewhat faster than floats or a lookup table, and is correct for # all inputs. -proc straight(c: RGBAColor): RGBAColor = +proc straight(c: RGBAColorPremul): RGBAColor = let a8 = c.a if a8 == 0: return RGBAColor(0) @@ -310,12 +316,12 @@ func blend*(c0, c1: RGBAColor): RGBAColor = let pc0 = c0.premul() let pc1 = c1.premul() let k = 255 - pc1.a - let mc = RGBAColor(fastmul1(pc0, uint32(k))) + let mc = fastmul1(pc0, uint32(k)) let rr = cast[uint8](uint16(pc1.r) + uint16(mc.r)) let rg = cast[uint8](uint16(pc1.g) + uint16(mc.g)) let rb = cast[uint8](uint16(pc1.b) + uint16(mc.b)) let ra = cast[uint8](uint16(pc1.a) + uint16(mc.a)) - let pres = rgba(rr, rg, rb, ra) + let pres = RGBAColorPremul(rgba(rr, rg, rb, ra)) let res = straight(pres) return res |