From 3edb6d62943d065964cb86e5f94b4b7a967cb23a Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Tue, 8 Dec 2020 22:36:33 -0600 Subject: [PATCH 1/5] more blends as just rgba --- src/pixie/blends.nim | 104 +++++++++++-------------------------------- 1 file changed, 27 insertions(+), 77 deletions(-) diff --git a/src/pixie/blends.nim b/src/pixie/blends.nim index 3b02119..278f079 100644 --- a/src/pixie/blends.nim +++ b/src/pixie/blends.nim @@ -126,12 +126,6 @@ proc alphaFix(Cb, Cs, mixed: Color): Color {.inline.} = result.g /= result.a result.b /= result.a -proc blendDarkenFloat(Cb, Cs: float32): float32 {.inline.} = - min(Cb, Cs) - -proc blendMultiplyFloat(Cb, Cs: float32): float32 {.inline.} = - Cb * Cs - proc blendLinearBurnFloat(Cb, Cs: float32): float32 {.inline.} = Cb + Cs - 1 @@ -140,9 +134,6 @@ proc blendColorBurnFloat(Cb, Cs: float32): float32 {.inline.} = elif Cs == 0: 0.0 else: 1.0 - min(1, (1 - Cb) / Cs) -proc blendLightenFloat(Cb, Cs: float32): float32 {.inline.} = - max(Cb, Cs) - proc blendScreenFloat(Cb, Cs: float32): float32 {.inline.} = screen(Cb, Cs) @@ -163,30 +154,9 @@ proc blendHardLightFloat(Cb, Cs: float32): float32 {.inline.} = proc blendSoftLightFloat(Cb, Cs: float32): float32 {.inline.} = softLight(Cb, Cs) -proc blendDifferenceFloat(Cb, Cs: float32): float32 {.inline.} = - abs(Cb - Cs) - proc blendExclusionFloat(Cb, Cs: float32): float32 {.inline.} = Cb + Cs - 2 * Cb * Cs -proc blendNormalFloats(Cb, Cs: Color): Color {.inline.} = - result.r = Cs.r - result.g = Cs.g - result.b = Cs.b - result = alphaFix(Cb, Cs, result) - -proc blendDarkenFloats(Cb, Cs: Color): Color {.inline.} = - result.r = blendDarkenFloat(Cb.r, Cs.r) - result.g = blendDarkenFloat(Cb.g, Cs.g) - result.b = blendDarkenFloat(Cb.b, Cs.b) - result = alphaFix(Cb, Cs, result) - -proc blendMultiplyFloats(Cb, Cs: Color): Color {.inline.} = - result.r = blendMultiplyFloat(Cb.r, Cs.r) - result.g = blendMultiplyFloat(Cb.g, Cs.g) - result.b = blendMultiplyFloat(Cb.b, Cs.b) - result = alphaFix(Cb, Cs, result) - proc blendLinearBurnFloats(Cb, Cs: Color): Color {.inline.} = result.r = blendLinearBurnFloat(Cb.r, Cs.r) result.g = blendLinearBurnFloat(Cb.g, Cs.g) @@ -199,12 +169,6 @@ proc blendColorBurnFloats(Cb, Cs: Color): Color {.inline.} = result.b = blendColorBurnFloat(Cb.b, Cs.b) result = alphaFix(Cb, Cs, result) -proc blendLightenFloats(Cb, Cs: Color): Color {.inline.} = - result.r = blendLightenFloat(Cb.r, Cs.r) - result.g = blendLightenFloat(Cb.g, Cs.g) - result.b = blendLightenFloat(Cb.b, Cs.b) - result = alphaFix(Cb, Cs, result) - proc blendScreenFloats(Cb, Cs: Color): Color {.inline.} = result.r = blendScreenFloat(Cb.r, Cs.r) result.g = blendScreenFloat(Cb.g, Cs.g) @@ -241,12 +205,6 @@ proc blendSoftLightFloats(Cb, Cs: Color): Color {.inline.} = result.b = blendSoftLightFloat(Cb.b, Cs.b) result = alphaFix(Cb, Cs, result) -proc blendDifferenceFloats(Cb, Cs: Color): Color {.inline.} = - result.r = blendDifferenceFloat(Cb.r, Cs.r) - result.g = blendDifferenceFloat(Cb.g, Cs.g) - result.b = blendDifferenceFloat(Cb.b, Cs.b) - result = alphaFix(Cb, Cs, result) - proc blendExclusionFloats(Cb, Cs: Color): Color {.inline.} = result.r = blendExclusionFloat(Cb.r, Cs.r) result.g = blendExclusionFloat(Cb.g, Cs.g) @@ -269,33 +227,6 @@ proc blendSaturationFloats(Cb, Cs: Color): Color {.inline.} = let mixed = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb)) alphaFix(Cb, Cs, mixed) -proc blendMaskFloats(target, blend: Color): Color {.inline.} = - result.r = target.r - result.g = target.g - result.b = target.b - result.a = min(target.a, blend.a) - -proc blendSubtractMaskFloats(target, blend: Color): Color {.inline.} = - result.r = target.r - result.g = target.g - result.b = target.b - result.a = target.a * (1 - blend.a) - -proc blendIntersectMaskFloats(target, blend: Color): Color {.inline.} = - result.r = target.r - result.g = target.g - result.b = target.b - result.a = target.a * blend.a - -proc blendExcludeMaskFloats(target, blend: Color): Color {.inline.} = - result.r = target.r - result.g = target.g - result.b = target.b - result.a = abs(target.a - blend.a) - -proc blendOverwriteFloats(target, blend: Color): Color {.inline.} = - result = blend - proc alphaFix(Cb, Cs, mixed: ColorRGBA): ColorRGBA {.inline.} = let ab = Cb.a.int32 let As = Cs.a.int32 @@ -319,10 +250,20 @@ proc blendNormal(a, b: ColorRGBA): ColorRGBA = result = alphaFix(a, b, result) proc blendDarken(a, b: ColorRGBA): ColorRGBA = - blendDarkenFloats(a.color, b.color).rgba + result.r = min(a.r, b.r) + result.g = min(a.g, b.g) + result.b = min(a.b, b.b) + result = alphaFix(a, b, result) proc blendMultiply(a, b: ColorRGBA): ColorRGBA = - blendMultiplyFloats(a.color, b.color).rgba + let + ac = a.color + bc = b.color + var c: Color + c.r = ac.r * bc.r + c.g = ac.g * bc.g + c.b = ac.b * bc.b + alphaFix(ac, bc, c).rgba proc blendLinearBurn(a, b: ColorRGBA): ColorRGBA = blendLinearBurnFloats(a.color, b.color).rgba @@ -331,7 +272,10 @@ proc blendColorBurn(a, b: ColorRGBA): ColorRGBA = blendColorBurnFloats(a.color, b.color).rgba proc blendLighten(a, b: ColorRGBA): ColorRGBA = - blendLightenFloats(a.color, b.color).rgba + result.r = max(a.r, b.r) + result.g = max(a.g, b.g) + result.b = max(a.b, b.b) + result = alphaFix(a, b, result) proc blendScreen(a, b: ColorRGBA): ColorRGBA = blendScreenFloats(a.color, b.color).rgba @@ -352,7 +296,10 @@ proc blendSoftLight(a, b: ColorRGBA): ColorRGBA = blendSoftLightFloats(a.color, b.color).rgba proc blendDifference(a, b: ColorRGBA): ColorRGBA = - blendDifferenceFloats(a.color, b.color).rgba + result.r = max(a.r, b.r) - min(a.r, b.r) + result.g = max(a.g, b.g) - min(a.g, b.g) + result.b = max(a.b, b.b) - min(a.b, b.b) + result = alphaFix(a, b, result) proc blendExclusion(a, b: ColorRGBA): ColorRGBA = blendExclusionFloats(a.color, b.color).rgba @@ -376,16 +323,19 @@ proc blendMask(a, b: ColorRGBA): ColorRGBA = result.a = min(a.a, b.a) proc blendSubtractMask(a, b: ColorRGBA): ColorRGBA = - blendSubtractMaskFloats(a.color, b.color).rgba + result = a + result.a = ((a.a.float32 / 255) * (1 - b.a.float32 / 255) * 255).uint8 proc blendIntersectMask(a, b: ColorRGBA): ColorRGBA = - blendIntersectMaskFloats(a.color, b.color).rgba + result = a + result.a = ((a.a.float32 / 255) * (b.a.float32 / 255) * 255).uint8 proc blendExcludeMask(a, b: ColorRGBA): ColorRGBA = - blendExcludeMaskFloats(a.color, b.color).rgba + result = a + result.a = max(a.a, b.a) - min(a.a, b.a) proc blendOverwrite(a, b: ColorRGBA): ColorRGBA = - blendOverwriteFloats(a.color, b.color).rgba + b proc mixer*(blendMode: BlendMode): Mixer = case blendMode From da9a68b04432d0e6035d1022847d6e38240c4a4a Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Wed, 9 Dec 2020 00:52:58 -0600 Subject: [PATCH 2/5] more --- src/pixie/blends.nim | 115 +++++++++++++++---------------------------- 1 file changed, 39 insertions(+), 76 deletions(-) diff --git a/src/pixie/blends.nim b/src/pixie/blends.nim index 278f079..3255883 100644 --- a/src/pixie/blends.nim +++ b/src/pixie/blends.nim @@ -69,15 +69,6 @@ proc `-`*(c: Color, v: float32): Color {.inline.} = result.b = c.b - v result.a = c.a - v -proc screen(Cb, Cs: float32): float32 {.inline.} = - 1 - (1 - Cb) * (1 - Cs) - -proc hardLight(Cb, Cs: float32): float32 {.inline.} = - if Cs <= 0.5: - Cb * 2 * Cs - else: - screen(Cb, 2 * Cs - 1) - proc softLight(a, b: float32): float32 {.inline.} = ## Pegtop (1 - 2 * b) * a ^ 2 + 2 * b * a @@ -126,91 +117,38 @@ proc alphaFix(Cb, Cs, mixed: Color): Color {.inline.} = result.g /= result.a result.b /= result.a -proc blendLinearBurnFloat(Cb, Cs: float32): float32 {.inline.} = - Cb + Cs - 1 - proc blendColorBurnFloat(Cb, Cs: float32): float32 {.inline.} = if Cb == 1: 1.0 elif Cs == 0: 0.0 else: 1.0 - min(1, (1 - Cb) / Cs) -proc blendScreenFloat(Cb, Cs: float32): float32 {.inline.} = - screen(Cb, Cs) - -proc blendLinearDodgeFloat(Cb, Cs: float32): float32 {.inline.} = - Cb + Cs proc blendColorDodgeFloat(Cb, Cs: float32): float32 {.inline.} = if Cb == 0: 0.0 elif Cs == 1: 1.0 else: min(1, Cb / (1 - Cs)) -proc blendOverlayFloat(Cb, Cs: float32): float32 {.inline.} = - hardLight(Cs, Cb) - -proc blendHardLightFloat(Cb, Cs: float32): float32 {.inline.} = - hardLight(Cb, Cs) - proc blendSoftLightFloat(Cb, Cs: float32): float32 {.inline.} = softLight(Cb, Cs) -proc blendExclusionFloat(Cb, Cs: float32): float32 {.inline.} = - Cb + Cs - 2 * Cb * Cs - -proc blendLinearBurnFloats(Cb, Cs: Color): Color {.inline.} = - result.r = blendLinearBurnFloat(Cb.r, Cs.r) - result.g = blendLinearBurnFloat(Cb.g, Cs.g) - result.b = blendLinearBurnFloat(Cb.b, Cs.b) - result = alphaFix(Cb, Cs, result) - proc blendColorBurnFloats(Cb, Cs: Color): Color {.inline.} = result.r = blendColorBurnFloat(Cb.r, Cs.r) result.g = blendColorBurnFloat(Cb.g, Cs.g) result.b = blendColorBurnFloat(Cb.b, Cs.b) result = alphaFix(Cb, Cs, result) -proc blendScreenFloats(Cb, Cs: Color): Color {.inline.} = - result.r = blendScreenFloat(Cb.r, Cs.r) - result.g = blendScreenFloat(Cb.g, Cs.g) - result.b = blendScreenFloat(Cb.b, Cs.b) - result = alphaFix(Cb, Cs, result) - -proc blendLinearDodgeFloats(Cb, Cs: Color): Color {.inline.} = - result.r = blendLinearDodgeFloat(Cb.r, Cs.r) - result.g = blendLinearDodgeFloat(Cb.g, Cs.g) - result.b = blendLinearDodgeFloat(Cb.b, Cs.b) - result = alphaFix(Cb, Cs, result) - proc blendColorDodgeFloats(Cb, Cs: Color): Color {.inline.} = result.r = blendColorDodgeFloat(Cb.r, Cs.r) result.g = blendColorDodgeFloat(Cb.g, Cs.g) result.b = blendColorDodgeFloat(Cb.b, Cs.b) result = alphaFix(Cb, Cs, result) -proc blendOverlayFloats(Cb, Cs: Color): Color {.inline.} = - result.r = blendOverlayFloat(Cb.r, Cs.r) - result.g = blendOverlayFloat(Cb.g, Cs.g) - result.b = blendOverlayFloat(Cb.b, Cs.b) - result = alphaFix(Cb, Cs, result) - -proc blendHardLightFloats(Cb, Cs: Color): Color {.inline.} = - result.r = blendHardLightFloat(Cb.r, Cs.r) - result.g = blendHardLightFloat(Cb.g, Cs.g) - result.b = blendHardLightFloat(Cb.b, Cs.b) - result = alphaFix(Cb, Cs, result) - proc blendSoftLightFloats(Cb, Cs: Color): Color {.inline.} = result.r = blendSoftLightFloat(Cb.r, Cs.r) result.g = blendSoftLightFloat(Cb.g, Cs.g) result.b = blendSoftLightFloat(Cb.b, Cs.b) result = alphaFix(Cb, Cs, result) -proc blendExclusionFloats(Cb, Cs: Color): Color {.inline.} = - result.r = blendExclusionFloat(Cb.r, Cs.r) - result.g = blendExclusionFloat(Cb.g, Cs.g) - result.b = blendExclusionFloat(Cb.b, Cs.b) - result = alphaFix(Cb, Cs, result) - proc blendColorFloats(Cb, Cs: Color): Color {.inline.} = let mixed = SetLum(Cs, Lum(Cb)) alphaFix(Cb, Cs, mixed) @@ -243,6 +181,15 @@ proc alphaFix(Cb, Cs, mixed: ColorRGBA): ColorRGBA {.inline.} = result.b = (b div a div 255).uint8 result.a = a.uint8 +proc screen(a, b: uint8): uint8 {.inline.} = + (255 - ((255 - a).uint32 * (255 - b).uint32) div 255).uint8 + +proc hardLight(a, b: uint8): uint8 {.inline.} = + if b <= 127: + ((a * 2 * b) div 255).uint8 + else: + screen(a, max(0, (2 * b.int32 - 255)).uint8) + proc blendNormal(a, b: ColorRGBA): ColorRGBA = result.r = b.r result.g = b.g @@ -256,17 +203,16 @@ proc blendDarken(a, b: ColorRGBA): ColorRGBA = result = alphaFix(a, b, result) proc blendMultiply(a, b: ColorRGBA): ColorRGBA = - let - ac = a.color - bc = b.color - var c: Color - c.r = ac.r * bc.r - c.g = ac.g * bc.g - c.b = ac.b * bc.b - alphaFix(ac, bc, c).rgba + result.r = ((a.r.uint32 * b.r.uint32) div 255).uint8 + result.g = ((a.g.uint32 * b.g.uint32) div 255).uint8 + result.b = ((a.b.uint32 * b.b.uint32) div 255).uint8 + result = alphaFix(a, b, result) proc blendLinearBurn(a, b: ColorRGBA): ColorRGBA = - blendLinearBurnFloats(a.color, b.color).rgba + result.r = max(0, a.r.int32 + b.r.int32 - 255).uint8 + result.g = max(0, a.g.int32 + b.g.int32 - 255).uint8 + result.b = max(0, a.b.int32 + b.b.int32 - 255).uint8 + result = alphaFix(a, b, result) proc blendColorBurn(a, b: ColorRGBA): ColorRGBA = blendColorBurnFloats(a.color, b.color).rgba @@ -278,19 +224,31 @@ proc blendLighten(a, b: ColorRGBA): ColorRGBA = result = alphaFix(a, b, result) proc blendScreen(a, b: ColorRGBA): ColorRGBA = - blendScreenFloats(a.color, b.color).rgba + result.r = screen(a.r, b.r) + result.g = screen(a.g, b.g) + result.b = screen(a.b, b.b) + result = alphaFix(a, b, result) proc blendLinearDodge(a, b: ColorRGBA): ColorRGBA = - blendLinearDodgeFloats(a.color, b.color).rgba + result.r = (a.r.uint32 + b.r).uint8 + result.r = (a.g.uint32 + b.g).uint8 + result.r = (a.b.uint32 + b.b).uint8 + result = alphaFix(a, b, result) proc blendColorDodge(a, b: ColorRGBA): ColorRGBA = blendColorDodgeFloats(a.color, b.color).rgba proc blendOverlay(a, b: ColorRGBA): ColorRGBA = - blendOverlayFloats(a.color, b.color).rgba + result.r = hardLight(b.r, a.r) + result.g = hardLight(b.g, a.g) + result.b = hardLight(b.b, a.b) + result = alphaFix(a, b, result) proc blendHardLight(a, b: ColorRGBA): ColorRGBA = - blendHardLightFloats(a.color, b.color).rgba + result.r = hardLight(a.r, b.r) + result.g = hardLight(a.g, b.g) + result.b = hardLight(a.b, b.b) + result = alphaFix(a, b, result) proc blendSoftLight(a, b: ColorRGBA): ColorRGBA = blendSoftLightFloats(a.color, b.color).rgba @@ -302,7 +260,12 @@ proc blendDifference(a, b: ColorRGBA): ColorRGBA = result = alphaFix(a, b, result) proc blendExclusion(a, b: ColorRGBA): ColorRGBA = - blendExclusionFloats(a.color, b.color).rgba + template blend(a, b: int32): uint8 = + max(0, a + b - (2 * a * b) div 255).uint8 + result.r = blend(a.r.int32, b.r.int32) + result.g = blend(a.g.int32, b.g.int32) + result.b = blend(a.b.int32, b.b.int32) + result = alphaFix(a, b, result) proc blendColor(a, b: ColorRGBA): ColorRGBA = blendColorFloats(a.color, b.color).rgba From 56dd24e2e9e300206681601ecfeec187a4b200d2 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Wed, 9 Dec 2020 00:55:46 -0600 Subject: [PATCH 3/5] f --- src/pixie/blends.nim | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pixie/blends.nim b/src/pixie/blends.nim index 3255883..b1e5e48 100644 --- a/src/pixie/blends.nim +++ b/src/pixie/blends.nim @@ -280,9 +280,7 @@ proc blendSaturation(a, b: ColorRGBA): ColorRGBA = blendSaturationFloats(a.color, b.color).rgba proc blendMask(a, b: ColorRGBA): ColorRGBA = - result.r = a.r - result.g = a.g - result.b = a.b + result = a result.a = min(a.a, b.a) proc blendSubtractMask(a, b: ColorRGBA): ColorRGBA = From 85b8967be15d62651cbf2ffbee967488fe60248d Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Wed, 9 Dec 2020 01:00:26 -0600 Subject: [PATCH 4/5] int --- src/pixie/blends.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pixie/blends.nim b/src/pixie/blends.nim index b1e5e48..14c9961 100644 --- a/src/pixie/blends.nim +++ b/src/pixie/blends.nim @@ -285,11 +285,11 @@ proc blendMask(a, b: ColorRGBA): ColorRGBA = proc blendSubtractMask(a, b: ColorRGBA): ColorRGBA = result = a - result.a = ((a.a.float32 / 255) * (1 - b.a.float32 / 255) * 255).uint8 + result.a = max(0, (a.a.int32 * (255 - b.a.int32)) div 255).uint8 proc blendIntersectMask(a, b: ColorRGBA): ColorRGBA = result = a - result.a = ((a.a.float32 / 255) * (b.a.float32 / 255) * 255).uint8 + result.a = ((a.a.uint32 * (b.a.uint32)) div 255).uint8 proc blendExcludeMask(a, b: ColorRGBA): ColorRGBA = result = a From 49624b6d03f33532930613d9d95c813afaabc085 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Wed, 9 Dec 2020 01:03:18 -0600 Subject: [PATCH 5/5] put back --- src/pixie/blends.nim | 131 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/src/pixie/blends.nim b/src/pixie/blends.nim index 14c9961..be23947 100644 --- a/src/pixie/blends.nim +++ b/src/pixie/blends.nim @@ -69,6 +69,15 @@ proc `-`*(c: Color, v: float32): Color {.inline.} = result.b = c.b - v result.a = c.a - v +proc screen(Cb, Cs: float32): float32 {.inline.} = + 1 - (1 - Cb) * (1 - Cs) + +proc hardLight(Cb, Cs: float32): float32 {.inline.} = + if Cs <= 0.5: + Cb * 2 * Cs + else: + screen(Cb, 2 * Cs - 1) + proc softLight(a, b: float32): float32 {.inline.} = ## Pegtop (1 - 2 * b) * a ^ 2 + 2 * b * a @@ -117,38 +126,133 @@ proc alphaFix(Cb, Cs, mixed: Color): Color {.inline.} = result.g /= result.a result.b /= result.a +proc blendDarkenFloat(Cb, Cs: float32): float32 {.inline.} = + min(Cb, Cs) + +proc blendMultiplyFloat(Cb, Cs: float32): float32 {.inline.} = + Cb * Cs + +proc blendLinearBurnFloat(Cb, Cs: float32): float32 {.inline.} = + Cb + Cs - 1 + proc blendColorBurnFloat(Cb, Cs: float32): float32 {.inline.} = if Cb == 1: 1.0 elif Cs == 0: 0.0 else: 1.0 - min(1, (1 - Cb) / Cs) +proc blendLightenFloat(Cb, Cs: float32): float32 {.inline.} = + max(Cb, Cs) + +proc blendScreenFloat(Cb, Cs: float32): float32 {.inline.} = + screen(Cb, Cs) + +proc blendLinearDodgeFloat(Cb, Cs: float32): float32 {.inline.} = + Cb + Cs proc blendColorDodgeFloat(Cb, Cs: float32): float32 {.inline.} = if Cb == 0: 0.0 elif Cs == 1: 1.0 else: min(1, Cb / (1 - Cs)) +proc blendOverlayFloat(Cb, Cs: float32): float32 {.inline.} = + hardLight(Cs, Cb) + +proc blendHardLightFloat(Cb, Cs: float32): float32 {.inline.} = + hardLight(Cb, Cs) + proc blendSoftLightFloat(Cb, Cs: float32): float32 {.inline.} = softLight(Cb, Cs) +proc blendDifferenceFloat(Cb, Cs: float32): float32 {.inline.} = + abs(Cb - Cs) + +proc blendExclusionFloat(Cb, Cs: float32): float32 {.inline.} = + Cb + Cs - 2 * Cb * Cs + +proc blendNormalFloats(Cb, Cs: Color): Color {.inline.} = + result.r = Cs.r + result.g = Cs.g + result.b = Cs.b + result = alphaFix(Cb, Cs, result) + +proc blendDarkenFloats(Cb, Cs: Color): Color {.inline.} = + result.r = blendDarkenFloat(Cb.r, Cs.r) + result.g = blendDarkenFloat(Cb.g, Cs.g) + result.b = blendDarkenFloat(Cb.b, Cs.b) + result = alphaFix(Cb, Cs, result) + +proc blendMultiplyFloats(Cb, Cs: Color): Color {.inline.} = + result.r = blendMultiplyFloat(Cb.r, Cs.r) + result.g = blendMultiplyFloat(Cb.g, Cs.g) + result.b = blendMultiplyFloat(Cb.b, Cs.b) + result = alphaFix(Cb, Cs, result) + +proc blendLinearBurnFloats(Cb, Cs: Color): Color {.inline.} = + result.r = blendLinearBurnFloat(Cb.r, Cs.r) + result.g = blendLinearBurnFloat(Cb.g, Cs.g) + result.b = blendLinearBurnFloat(Cb.b, Cs.b) + result = alphaFix(Cb, Cs, result) + proc blendColorBurnFloats(Cb, Cs: Color): Color {.inline.} = result.r = blendColorBurnFloat(Cb.r, Cs.r) result.g = blendColorBurnFloat(Cb.g, Cs.g) result.b = blendColorBurnFloat(Cb.b, Cs.b) result = alphaFix(Cb, Cs, result) +proc blendLightenFloats(Cb, Cs: Color): Color {.inline.} = + result.r = blendLightenFloat(Cb.r, Cs.r) + result.g = blendLightenFloat(Cb.g, Cs.g) + result.b = blendLightenFloat(Cb.b, Cs.b) + result = alphaFix(Cb, Cs, result) + +proc blendScreenFloats(Cb, Cs: Color): Color {.inline.} = + result.r = blendScreenFloat(Cb.r, Cs.r) + result.g = blendScreenFloat(Cb.g, Cs.g) + result.b = blendScreenFloat(Cb.b, Cs.b) + result = alphaFix(Cb, Cs, result) + +proc blendLinearDodgeFloats(Cb, Cs: Color): Color {.inline.} = + result.r = blendLinearDodgeFloat(Cb.r, Cs.r) + result.g = blendLinearDodgeFloat(Cb.g, Cs.g) + result.b = blendLinearDodgeFloat(Cb.b, Cs.b) + result = alphaFix(Cb, Cs, result) + proc blendColorDodgeFloats(Cb, Cs: Color): Color {.inline.} = result.r = blendColorDodgeFloat(Cb.r, Cs.r) result.g = blendColorDodgeFloat(Cb.g, Cs.g) result.b = blendColorDodgeFloat(Cb.b, Cs.b) result = alphaFix(Cb, Cs, result) +proc blendOverlayFloats(Cb, Cs: Color): Color {.inline.} = + result.r = blendOverlayFloat(Cb.r, Cs.r) + result.g = blendOverlayFloat(Cb.g, Cs.g) + result.b = blendOverlayFloat(Cb.b, Cs.b) + result = alphaFix(Cb, Cs, result) + +proc blendHardLightFloats(Cb, Cs: Color): Color {.inline.} = + result.r = blendHardLightFloat(Cb.r, Cs.r) + result.g = blendHardLightFloat(Cb.g, Cs.g) + result.b = blendHardLightFloat(Cb.b, Cs.b) + result = alphaFix(Cb, Cs, result) + proc blendSoftLightFloats(Cb, Cs: Color): Color {.inline.} = result.r = blendSoftLightFloat(Cb.r, Cs.r) result.g = blendSoftLightFloat(Cb.g, Cs.g) result.b = blendSoftLightFloat(Cb.b, Cs.b) result = alphaFix(Cb, Cs, result) +proc blendDifferenceFloats(Cb, Cs: Color): Color {.inline.} = + result.r = blendDifferenceFloat(Cb.r, Cs.r) + result.g = blendDifferenceFloat(Cb.g, Cs.g) + result.b = blendDifferenceFloat(Cb.b, Cs.b) + result = alphaFix(Cb, Cs, result) + +proc blendExclusionFloats(Cb, Cs: Color): Color {.inline.} = + result.r = blendExclusionFloat(Cb.r, Cs.r) + result.g = blendExclusionFloat(Cb.g, Cs.g) + result.b = blendExclusionFloat(Cb.b, Cs.b) + result = alphaFix(Cb, Cs, result) + proc blendColorFloats(Cb, Cs: Color): Color {.inline.} = let mixed = SetLum(Cs, Lum(Cb)) alphaFix(Cb, Cs, mixed) @@ -165,6 +269,33 @@ proc blendSaturationFloats(Cb, Cs: Color): Color {.inline.} = let mixed = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb)) alphaFix(Cb, Cs, mixed) +proc blendMaskFloats(target, blend: Color): Color {.inline.} = + result.r = target.r + result.g = target.g + result.b = target.b + result.a = min(target.a, blend.a) + +proc blendSubtractMaskFloats(target, blend: Color): Color {.inline.} = + result.r = target.r + result.g = target.g + result.b = target.b + result.a = target.a * (1 - blend.a) + +proc blendIntersectMaskFloats(target, blend: Color): Color {.inline.} = + result.r = target.r + result.g = target.g + result.b = target.b + result.a = target.a * blend.a + +proc blendExcludeMaskFloats(target, blend: Color): Color {.inline.} = + result.r = target.r + result.g = target.g + result.b = target.b + result.a = abs(target.a - blend.a) + +proc blendOverwriteFloats(target, blend: Color): Color {.inline.} = + result = blend + proc alphaFix(Cb, Cs, mixed: ColorRGBA): ColorRGBA {.inline.} = let ab = Cb.a.int32 let As = Cs.a.int32