consistent names, alphaFix 80char

This commit is contained in:
Ryan Oldenburg 2020-12-09 04:09:22 -06:00
parent 78b1dbab03
commit 1ad2f3e05f

View file

@ -69,42 +69,38 @@ 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 screen(backdrop, source: float32): float32 {.inline.} =
1 - (1 - backdrop) * (1 - source)
proc hardLight(Cb, Cs: float32): float32 {.inline.} =
if Cs <= 0.5:
Cb * 2 * Cs
proc hardLight(backdrop, source: float32): float32 {.inline.} =
if source <= 0.5:
backdrop * 2 * source
else:
screen(Cb, 2 * Cs - 1)
screen(backdrop, 2 * source - 1)
proc softLight(a, b: float32): float32 {.inline.} =
proc softLight(backdrop, source: float32): float32 {.inline.} =
## Pegtop
(1 - 2 * b) * a ^ 2 + 2 * b * a
(1 - 2 * source) * backdrop ^ 2 + 2 * source * backdrop
proc Lum(C: Color): float32 {.inline.} =
0.3 * C.r + 0.59 * C.g + 0.11 * C.b
proc ClipColor(C: Color): Color {.inline.} =
proc ClipColor(C: var Color) {.inline.} =
let
L = Lum(C)
n = min([C.r, C.g, C.b])
x = max([C.r, C.g, C.b])
var
C = C
if n < 0:
C = L + (((C - L) * L) / (L - n))
if x > 1:
C = L + (((C - L) * (1 - L)) / (x - L))
return C
proc SetLum(C: Color, l: float32): Color {.inline.} =
let
d = l - Lum(C)
let d = l - Lum(C)
result.r = C.r + d
result.g = C.g + d
result.b = C.b + d
return ClipColor(result)
ClipColor(result)
proc Sat(C: Color): float32 {.inline.} =
max([C.r, C.g, C.b]) - min([C.r, C.g, C.b])
@ -114,266 +110,249 @@ proc SetSat(C: Color, s: float32): Color {.inline.} =
if satC > 0:
result = (C - min([C.r, C.g, C.b])) * s / satC
proc alphaFix(Cb, Cs, mixed: Color): Color {.inline.} =
let ab = Cb.a
let As = Cs.a
result.r = As * (1 - ab) * Cs.r + As * ab * mixed.r + (1 - As) * ab * Cb.r
result.g = As * (1 - ab) * Cs.g + As * ab * mixed.g + (1 - As) * ab * Cb.g
result.b = As * (1 - ab) * Cs.b + As * ab * mixed.b + (1 - As) * ab * Cb.b
proc alphaFix(backdrop, source, mixed: Color): Color =
let
t0 = source.a * (1 - backdrop.a)
t1 = source.a * backdrop.a
t2 = (1 - source.a) * backdrop.a
result.a = (Cs.a + Cb.a * (1.0 - Cs.a))
result.r = t0 * source.r + t1 * mixed.r + t2 * backdrop.r
result.g = t0 * source.g + t1 * mixed.g + t2 * backdrop.g
result.b = t0 * source.b + t1 * mixed.b + t2 * backdrop.b
result.a = (source.a + backdrop.a * (1.0 - source.a))
result.r /= result.a
result.g /= result.a
result.b /= result.a
proc blendDarkenFloat(Cb, Cs: float32): float32 {.inline.} =
min(Cb, Cs)
proc blendNormalFloats(backdrop, source: Color): Color {.inline.} =
result = source
result = alphaFix(backdrop, source, result)
proc blendMultiplyFloat(Cb, Cs: float32): float32 {.inline.} =
Cb * Cs
proc blendDarkenFloats(backdrop, source: Color): Color {.inline.} =
result.r = min(backdrop.r, source.r)
result.g = min(backdrop.g, source.g)
result.b = min(backdrop.b, source.b)
result = alphaFix(backdrop, source, result)
proc blendLinearBurnFloat(Cb, Cs: float32): float32 {.inline.} =
Cb + Cs - 1
proc blendMultiplyFloats(backdrop, source: Color): Color {.inline.} =
result.r = backdrop.r * source.r
result.g = backdrop.g * source.g
result.b = backdrop.b * source.b
result = alphaFix(backdrop, source, result)
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 blendLinearBurnFloats(backdrop, source: Color): Color {.inline.} =
result.r = backdrop.r + source.r - 1
result.g = backdrop.g + source.g - 1
result.b = backdrop.b + source.b - 1
result = alphaFix(backdrop, source, result)
proc blendLightenFloat(Cb, Cs: float32): float32 {.inline.} =
max(Cb, Cs)
proc blendColorBurnFloats(backdrop, source: Color): Color {.inline.} =
proc blend(backdrop, source: float32): float32 {.inline.} =
if backdrop == 1:
1.0
elif source == 0:
0.0
else:
1.0 - min(1, (1 - backdrop) / source)
result.r = blend(backdrop.r, source.r)
result.g = blend(backdrop.g, source.g)
result.b = blend(backdrop.b, source.b)
result = alphaFix(backdrop, source, result)
proc blendScreenFloat(Cb, Cs: float32): float32 {.inline.} =
screen(Cb, Cs)
proc blendLightenFloats(backdrop, source: Color): Color {.inline.} =
result.r = max(backdrop.r, source.r)
result.g = max(backdrop.g, source.g)
result.b = max(backdrop.b, source.b)
result = alphaFix(backdrop, source, result)
proc blendLinearDodgeFloat(Cb, Cs: float32): float32 {.inline.} =
Cb + Cs
proc blendScreenFloats(backdrop, source: Color): Color {.inline.} =
result.r = screen(backdrop.r, source.r)
result.g = screen(backdrop.g, source.g)
result.b = screen(backdrop.b, source.b)
result = alphaFix(backdrop, source, result)
proc blendColorDodgeFloat(Cb, Cs: float32): float32 {.inline.} =
if Cb == 0: 0.0
elif Cs == 1: 1.0
else: min(1, Cb / (1 - Cs))
proc blendLinearDodgeFloats(backdrop, source: Color): Color {.inline.} =
result.r = backdrop.r + source.r
result.g = backdrop.g + source.g
result.b = backdrop.b + source.b
result = alphaFix(backdrop, source, result)
proc blendOverlayFloat(Cb, Cs: float32): float32 {.inline.} =
hardLight(Cs, Cb)
proc blendColorDodgeFloats(backdrop, source: Color): Color {.inline.} =
proc blend(backdrop, source: float32): float32 {.inline.} =
if backdrop == 0:
0.0
elif source == 1:
1.0
else:
min(1, backdrop / (1 - source))
result.r = blend(backdrop.r, source.r)
result.g = blend(backdrop.g, source.g)
result.b = blend(backdrop.b, source.b)
result = alphaFix(backdrop, source, result)
proc blendHardLightFloat(Cb, Cs: float32): float32 {.inline.} =
hardLight(Cb, Cs)
proc blendOverlayFloats(backdrop, source: Color): Color {.inline.} =
result.r = hardLight(source.r, backdrop.r)
result.g = hardLight(source.g, backdrop.g)
result.b = hardLight(source.b, backdrop.b)
result = alphaFix(backdrop, source, result)
proc blendSoftLightFloat(Cb, Cs: float32): float32 {.inline.} =
softLight(Cb, Cs)
proc blendHardLightFloats(backdrop, source: Color): Color {.inline.} =
result.r = hardLight(backdrop.r, source.r)
result.g = hardLight(backdrop.g, source.g)
result.b = hardLight(backdrop.b, source.b)
result = alphaFix(backdrop, source, result)
proc blendDifferenceFloat(Cb, Cs: float32): float32 {.inline.} =
abs(Cb - Cs)
proc blendSoftLightFloats(backdrop, source: Color): Color {.inline.} =
result.r = softLight(backdrop.r, source.r)
result.g = softLight(backdrop.g, source.g)
result.b = softLight(backdrop.b, source.b)
result = alphaFix(backdrop, source, result)
proc blendExclusionFloat(Cb, Cs: float32): float32 {.inline.} =
Cb + Cs - 2 * Cb * Cs
proc blendDifferenceFloats(backdrop, source: Color): Color {.inline.} =
result.r = abs(backdrop.r - source.r)
result.g = abs(backdrop.g - source.g)
result.b = abs(backdrop.b - source.b)
result = alphaFix(backdrop, source, result)
proc blendNormalFloats(Cb, Cs: Color): Color {.inline.} =
result = Cs
result = alphaFix(Cb, Cs, result)
proc blendExclusionFloats(backdrop, source: Color): Color {.inline.} =
proc blend(backdrop, source: float32): float32 {.inline.} =
backdrop + source - 2 * backdrop * source
result.r = blend(backdrop.r, source.r)
result.g = blend(backdrop.g, source.g)
result.b = blend(backdrop.b, source.b)
result = alphaFix(backdrop, source, 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 blendColorFloats(backdrop, source: Color): Color {.inline.} =
result = SetLum(source, Lum(backdrop))
result = alphaFix(backdrop, source, 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 blendLuminosityFloats(backdrop, source: Color): Color {.inline.} =
result = SetLum(backdrop, Lum(source))
result = alphaFix(backdrop, source, 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 blendHueFloats(backdrop, source: Color): Color {.inline.} =
result = SetLum(SetSat(source, Sat(backdrop)), Lum(backdrop))
result = alphaFix(backdrop, source, 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 blendSaturationFloats(backdrop, source: Color): Color {.inline.} =
result = SetLum(SetSat(backdrop, Sat(source)), Lum(backdrop))
result = alphaFix(backdrop, source, 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 blendMaskFloats(backdrop, source: Color): Color {.inline.} =
result = backdrop
result.a = min(backdrop.a, source.a)
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 blendSubtractMaskFloats(backdrop, source: Color): Color {.inline.} =
result = backdrop
result.a = backdrop.a * (1 - source.a)
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 blendIntersectMaskFloats(backdrop, source: Color): Color {.inline.} =
result = backdrop
result.a = backdrop.a * source.a
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 blendExcludeMaskFloats(backdrop, source: Color): Color {.inline.} =
result = backdrop
result.a = abs(backdrop.a - source.a)
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 blendOverwriteFloats(backdrop, source: Color): Color {.inline.} =
source
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 alphaFix(backdrop, source, mixed: ColorRGBA): ColorRGBA {.inline.} =
let
sa = source.a.int32
ba = backdrop.a.int32
t0 = sa * (255 - ba)
t1 = sa * ba
t2 = (255 - sa) * ba
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)
let
r = t0 * source.r.int32 + t1 * mixed.r.int32 + t2 * backdrop.r.int32
g = t0 * source.g.int32 + t1 * mixed.g.int32 + t2 * backdrop.g.int32
b = t0 * source.b.int32 + t1 * mixed.b.int32 + t2 * backdrop.b.int32
a = sa + ba * (255 - sa) div 255
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)
proc blendLuminosityFloats(Cb, Cs: Color): Color {.inline.} =
let mixed = SetLum(Cb, Lum(Cs))
alphaFix(Cb, Cs, mixed)
proc blendHueFloats(Cb, Cs: Color): Color {.inline.} =
let mixed = SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb))
alphaFix(Cb, Cs, mixed)
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 = target
result.a = min(target.a, blend.a)
proc blendSubtractMaskFloats(target, blend: Color): Color {.inline.} =
result = target
result.a = target.a * (1 - blend.a)
proc blendIntersectMaskFloats(target, blend: Color): Color {.inline.} =
result = target
result.a = target.a * blend.a
proc blendExcludeMaskFloats(target, blend: Color): Color {.inline.} =
result = target
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
let r = As * (255 - ab) * Cs.r.int32 + As * ab * mixed.r.int32 + (255 - As) * ab * Cb.r.int32
let g = As * (255 - ab) * Cs.g.int32 + As * ab * mixed.g.int32 + (255 - As) * ab * Cb.g.int32
let b = As * (255 - ab) * Cs.b.int32 + As * ab * mixed.b.int32 + (255 - As) * ab * Cb.b.int32
let a = Cs.a.int32 + Cb.a.int32 * (255 - Cs.a.int32) div 255
if a == 0:
return
else:
result.r = (r div a div 255).uint8
result.g = (g div a div 255).uint8
result.b = (b div a div 255).uint8
result.a = a.uint8
proc blendNormal(a, b: ColorRGBA): ColorRGBA =
blendNormalFloats(a.color, b.color).rgba
result.r = (r div a div 255).uint8
result.g = (g div a div 255).uint8
result.b = (b div a div 255).uint8
result.a = a.uint8
proc blendDarken(a, b: ColorRGBA): ColorRGBA =
blendDarkenFloats(a.color, b.color).rgba
proc blendNormal(backdrop, source: ColorRGBA): ColorRGBA =
result = source
result = alphaFix(backdrop, source, result)
proc blendMultiply(a, b: ColorRGBA): ColorRGBA =
blendMultiplyFloats(a.color, b.color).rgba
proc blendDarken(backdrop, source: ColorRGBA): ColorRGBA =
blendDarkenFloats(backdrop.color, source.color).rgba
proc blendLinearBurn(a, b: ColorRGBA): ColorRGBA =
blendLinearBurnFloats(a.color, b.color).rgba
proc blendMultiply(backdrop, source: ColorRGBA): ColorRGBA =
blendMultiplyFloats(backdrop.color, source.color).rgba
proc blendColorBurn(a, b: ColorRGBA): ColorRGBA =
blendColorBurnFloats(a.color, b.color).rgba
proc blendLinearBurn(backdrop, source: ColorRGBA): ColorRGBA =
blendLinearBurnFloats(backdrop.color, source.color).rgba
proc blendLighten(a, b: ColorRGBA): ColorRGBA =
blendLightenFloats(a.color, b.color).rgba
proc blendColorBurn(backdrop, source: ColorRGBA): ColorRGBA =
blendColorBurnFloats(backdrop.color, source.color).rgba
proc blendScreen(a, b: ColorRGBA): ColorRGBA =
blendScreenFloats(a.color, b.color).rgba
proc blendLighten(backdrop, source: ColorRGBA): ColorRGBA =
blendLightenFloats(backdrop.color, source.color).rgba
proc blendLinearDodge(a, b: ColorRGBA): ColorRGBA =
blendLinearDodgeFloats(a.color, b.color).rgba
proc blendScreen(backdrop, source: ColorRGBA): ColorRGBA =
blendScreenFloats(backdrop.color, source.color).rgba
proc blendColorDodge(a, b: ColorRGBA): ColorRGBA =
blendColorDodgeFloats(a.color, b.color).rgba
proc blendLinearDodge(backdrop, source: ColorRGBA): ColorRGBA =
blendLinearDodgeFloats(backdrop.color, source.color).rgba
proc blendOverlay(a, b: ColorRGBA): ColorRGBA =
blendOverlayFloats(a.color, b.color).rgba
proc blendColorDodge(backdrop, source: ColorRGBA): ColorRGBA =
blendColorDodgeFloats(backdrop.color, source.color).rgba
proc blendHardLight(a, b: ColorRGBA): ColorRGBA =
blendHardLightFloats(a.color, b.color).rgba
proc blendOverlay(backdrop, source: ColorRGBA): ColorRGBA =
blendOverlayFloats(backdrop.color, source.color).rgba
proc blendSoftLight(a, b: ColorRGBA): ColorRGBA =
blendSoftLightFloats(a.color, b.color).rgba
proc blendHardLight(backdrop, source: ColorRGBA): ColorRGBA =
blendHardLightFloats(backdrop.color, source.color).rgba
proc blendDifference(a, b: ColorRGBA): ColorRGBA =
blendDifferenceFloats(a.color, b.color).rgba
proc blendSoftLight(backdrop, source: ColorRGBA): ColorRGBA =
blendSoftLightFloats(backdrop.color, source.color).rgba
proc blendExclusion(a, b: ColorRGBA): ColorRGBA =
blendExclusionFloats(a.color, b.color).rgba
proc blendDifference(backdrop, source: ColorRGBA): ColorRGBA =
blendDifferenceFloats(backdrop.color, source.color).rgba
proc blendColor(a, b: ColorRGBA): ColorRGBA =
blendColorFloats(a.color, b.color).rgba
proc blendExclusion(backdrop, source: ColorRGBA): ColorRGBA =
blendExclusionFloats(backdrop.color, source.color).rgba
proc blendLuminosity(a, b: ColorRGBA): ColorRGBA =
blendLuminosityFloats(a.color, b.color).rgba
proc blendColor(backdrop, source: ColorRGBA): ColorRGBA =
blendColorFloats(backdrop.color, source.color).rgba
proc blendHue(a, b: ColorRGBA): ColorRGBA =
blendHueFloats(a.color, b.color).rgba
proc blendLuminosity(backdrop, source: ColorRGBA): ColorRGBA =
blendLuminosityFloats(backdrop.color, source.color).rgba
proc blendSaturation(a, b: ColorRGBA): ColorRGBA =
blendSaturationFloats(a.color, b.color).rgba
proc blendHue(backdrop, source: ColorRGBA): ColorRGBA =
blendHueFloats(backdrop.color, source.color).rgba
proc blendMask(a, b: ColorRGBA): ColorRGBA =
result = a
result.a = min(a.a, b.a)
proc blendSaturation(backdrop, source: ColorRGBA): ColorRGBA =
blendSaturationFloats(backdrop.color, source.color).rgba
proc blendSubtractMask(a, b: ColorRGBA): ColorRGBA =
result = a
result.a = max(0, (a.a.int32 * (255 - b.a.int32)) div 255).uint8
proc blendMask(backdrop, source: ColorRGBA): ColorRGBA =
result = backdrop
result.a = min(backdrop.a, source.a)
proc blendIntersectMask(a, b: ColorRGBA): ColorRGBA =
result = a
result.a = ((a.a.uint32 * (b.a.uint32)) div 255).uint8
proc blendSubtractMask(backdrop, source: ColorRGBA): ColorRGBA =
result = backdrop
result.a = max(0, (backdrop.a.int32 * (255 - source.a.int32)) div 255).uint8
proc blendExcludeMask(a, b: ColorRGBA): ColorRGBA =
result = a
result.a = max(a.a, b.a) - min(a.a, b.a)
proc blendIntersectMask(backdrop, source: ColorRGBA): ColorRGBA =
result = backdrop
result.a = ((backdrop.a.uint32 * (source.a.uint32)) div 255).uint8
proc blendOverwrite(a, b: ColorRGBA): ColorRGBA =
b
proc blendExcludeMask(backdrop, source: ColorRGBA): ColorRGBA =
result = backdrop
result.a = max(backdrop.a, source.a) - min(backdrop.a, source.a)
proc blendOverwrite(backdrop, source: ColorRGBA): ColorRGBA =
source
proc mixer*(blendMode: BlendMode): Mixer =
case blendMode