about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-07-07 13:35:15 +0200
committerbptato <nincsnevem662@gmail.com>2023-07-07 13:35:15 +0200
commitb2514e94bac6f7b3462649834ad36287b0b29ab2 (patch)
treeb1ecd39ba2b1227794e3edebfd4deb07332dd0d9
parent01ce4740d41b1e00b1f9735f80a010f324b6f583 (diff)
downloadchawan-b2514e94bac6f7b3462649834ad36287b0b29ab2.tar.gz
Add separate type for premultiplied color
-rw-r--r--src/types/color.nim26
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