@@ -115,6 +115,18 @@ channels(c::TransparentGray) = (gray(c), alpha(c))
115115channels (c:: AbstractRGB ) = (red (c), green (c), blue (c))
116116channels (c:: TransparentRGB ) = (red (c), green (c), blue (c), alpha (c))
117117
118+ _add (x:: T , y:: T ) where {T} = x + y
119+ _add (x, y) = sumtype (typeof (x), typeof (y))(x + y)
120+ _add (x:: FixedPoint , y:: Integer ) = sumtype (typeof (x), typeof (y))(x + y % typeof (x))
121+ _add (x:: Integer , y:: FixedPoint ) = sumtype (typeof (x), typeof (y))(x % typeof (y) + y)
122+ _add (x:: Bool , y:: Bool ) = x ⊻ y
123+
124+ _sub (x:: T , y:: T ) where {T} = x - y
125+ _sub (x, y) = sumtype (typeof (x), typeof (y))(x - y)
126+ _sub (x:: FixedPoint , y:: Integer ) = sumtype (typeof (x), typeof (y))(x - y % typeof (x))
127+ _sub (x:: Integer , y:: FixedPoint ) = sumtype (typeof (x), typeof (y))(x % typeof (y) - y)
128+ _sub (x:: Bool , y:: Bool ) = x ⊻ y
129+
118130# TODO : Remove the specialized `_mul`s when dropping FixedPointNumbers v0.8 support
119131if reinterpret (N0f16, 0xBADb )^ 2 === N0f16 (float (reinterpret (N0f16, 0xBADb ))^ 2 )
120132 function _mul (x:: N0f8 , y:: N0f8 )
@@ -231,10 +243,10 @@ function (/)(c::C, f::AbstractFloat) where {C<:Union{AbstractRGB, TransparentRGB
231243 r = oneunit (divtype (eltype (c), typeof (f))) / f
232244 _mapc (rettype (/ , c, f), v -> v * r, c)
233245end
234- (+ )(a:: AbstractRGB , b:: AbstractRGB ) = _mapc (rettype (+ , a, b), + , a, b)
235- (- )(a:: AbstractRGB , b:: AbstractRGB ) = _mapc (rettype (- , a, b), - , a, b)
236- (+ )(a:: TransparentRGB , b:: TransparentRGB ) = _mapc (rettype (+ , a, b), + , a, b)
237- (- )(a:: TransparentRGB , b:: TransparentRGB ) = _mapc (rettype (- , a, b), - , a, b)
246+ (+ )(a:: AbstractRGB , b:: AbstractRGB ) = _mapc (rettype (+ , a, b), _add , a, b)
247+ (- )(a:: AbstractRGB , b:: AbstractRGB ) = _mapc (rettype (- , a, b), _sub , a, b)
248+ (+ )(a:: TransparentRGB , b:: TransparentRGB ) = _mapc (rettype (+ , a, b), _add , a, b)
249+ (- )(a:: TransparentRGB , b:: TransparentRGB ) = _mapc (rettype (- , a, b), _sub , a, b)
238250
239251# New multiplication operators
240252function (⋅ )(x:: C , y:: C ) where C <: AbstractRGB # ambiguity fix
@@ -273,26 +285,32 @@ middle(c::AbstractGray) = arith_colorant_type(c)(middle(gray(c)))
273285middle (x:: C , y:: C ) where {C<: AbstractGray } = arith_colorant_type (C)(middle (gray (x), gray (y)))
274286
275287(/ )(n:: Number , c:: AbstractGray ) = base_color_type (c)(_div (real (n), gray (c)))
276- (+ )(a:: AbstractGray , b:: AbstractGray ) = _mapc (rettype (+ , a, b), + , a, b)
277- (+ )(a:: AbstractGray{Bool} , b:: AbstractGray{Bool} ) = _mapc (rettype (+ , a, b), ⊻ , a, b)
278- (+ )(a:: TransparentGray , b:: TransparentGray ) = _mapc (rettype (+ , a, b), + , a, b)
279- (- )(a:: AbstractGray , b:: AbstractGray ) = _mapc (rettype (- , a, b), - , a, b)
280- (- )(a:: AbstractGray{Bool} , b:: AbstractGray{Bool} ) = _mapc (rettype (- , a, b), ⊻ , a, b)
281- (- )(a:: TransparentGray , b:: TransparentGray ) = _mapc (rettype (- , a, b), - , a, b)
288+ (+ )(a:: AbstractGray , b:: AbstractGray ) = _mapc (rettype (+ , a, b), _add, a, b)
289+ (+ )(a:: TransparentGray , b:: TransparentGray ) = _mapc (rettype (+ , a, b), _add, a, b)
290+ (- )(a:: AbstractGray , b:: AbstractGray ) = _mapc (rettype (- , a, b), _sub, a, b)
291+ (- )(a:: TransparentGray , b:: TransparentGray ) = _mapc (rettype (- , a, b), _sub, a, b)
282292(* )(a:: AbstractGray , b:: AbstractGray ) = a ⊙ b
283293(^ )(a:: AbstractGray , b:: Integer ) = rettype (^ , a, b)(gray (a)^ (b isa Bool ? b : convert (Int, b)))
284294(^ )(a:: AbstractGray , b:: Real ) = rettype (^ , a, b)(gray (a)^ b)
285295(/ )(a:: AbstractGray , b:: AbstractGray ) = rettype (/ , a, b)(_div (gray (a), gray (b)))
286- (+ )(a:: AbstractGray , b:: Number ) = base_color_type (a)(gray (a)+ b)
287- (+ )(a:: AbstractGray{Bool} , b:: Number ) = arith_colorant_type (a){sumtype (Bool, typeof (b))}(gray (a) + b)
288- (+ )(a:: AbstractGray{Bool} , b:: Bool ) = a + sumtype (Bool, Bool)(b)
289- (+ )(a:: Number , b:: AbstractGray ) = b+ a
290- (- )(a:: AbstractGray , b:: Number ) = base_color_type (a)(gray (a)- b)
291- (- )(a:: Number , b:: AbstractGray ) = base_color_type (b)(a- gray (b))
292- (- )(a:: AbstractGray{Bool} , b:: Number ) = arith_colorant_type (a){sumtype (Bool, typeof (b))}(gray (a) - b)
293- (- )(a:: Number , b:: AbstractGray{Bool} ) = arith_colorant_type (b){sumtype (typeof (a), Bool)}(a - gray (b))
294- (- )(a:: AbstractGray{Bool} , b:: Bool ) = a - sumtype (Bool, Bool)(b)
295- (- )(a:: Bool , b:: AbstractGray{Bool} ) = sumtype (Bool, Bool)(a) - b
296+ # TODO : Drop support for FixedPointNumbers v0.8 and change the handling to
297+ # follow the promotion rules for FixedPointNumbers v0.9.
298+ function (+ )(a:: AbstractGray , b:: Number )
299+ gray (a) isa Bool && b isa Bool && return base_color_type (a)((gray (a) + b) % sumtype (Bool, Bool))
300+ return base_color_type (a)(_add (gray (a), b))
301+ end
302+ function (+ )(a:: Number , b:: AbstractGray )
303+ a isa Bool && gray (b) isa Bool && return base_color_type (b)((a + gray (b)) % sumtype (Bool, Bool))
304+ return base_color_type (a)(_add (a, gray (b)))
305+ end
306+ function (- )(a:: AbstractGray , b:: Number )
307+ gray (a) isa Bool && b isa Bool && return base_color_type (a)((gray (a) - b) % sumtype (Bool, Bool))
308+ return base_color_type (a)(_sub (gray (a), b))
309+ end
310+ function (- )(a:: Number , b:: AbstractGray )
311+ a isa Bool && gray (b) isa Bool && return base_color_type (b)((a - gray (b)) % sumtype (Bool, Bool))
312+ return base_color_type (a)(_sub (a, gray (b)))
313+ end
296314
297315(⋅ )(x:: C , y:: C ) where {C<: AbstractGray } = _mul (gray (x), gray (y))
298316(⊗ )(x:: C , y:: C ) where {C<: AbstractGray } = x ⊙ y
0 commit comments