func blend()

in Cyborg/VectorDrawable.swift [661:722]


    func blend(src: UIColor, dst: UIColor) -> UIColor {
        let (sr, sg, sb, sa) = src.rgba
        let (dr, dg, db, da) = dst.rgba
        func clamp(_ float: CGFloat) -> CGFloat {
            max(0, min(float, 1))
        }
        func createColor(_ color: (CGFloat, CGFloat) -> CGFloat,
                         _ alpha: (CGFloat, CGFloat) -> CGFloat) -> UIColor {
            UIColor(red: clamp(color(sr, dr)),
                    green: clamp(color(sg, dg)),
                    blue: clamp(color(sb, db)),
                    alpha: clamp(alpha(sa, da)))
        }
        switch self {
        case .add:
            return createColor(+, +)
        case .clear:
            return createColor({ _, _ in 0 }, { _, _ in 0 })
        case .darken:
            return createColor({ (src: CGFloat, dst: CGFloat) -> CGFloat in (1 - da) * src + (1 - sa) * dst + min(src, dst) },
                               { src, dst in src + dst - (src * dst) })
        case .dst:
            return dst
        case .dstAtop:
            return createColor({ src, dst in sa * dst + (1 - da) * src }, { _, dst in dst })
        case .dstIn:
            return createColor({ src, dst in dst * sa }, { src, dst in src * dst })
        case .dstOut:
            return createColor({ src, dst in (1 - sa) * dst }, { src, dst in (1 - src) * dst })
        case .dstOver:
            return createColor({ src, dst in dst + (1 - da) * src }, { src, dst in da + ( 1 - da) * sa })
        case .lighten:
            return createColor({ (src: CGFloat, dst: CGFloat) in ( 1 - da) * src + (1 - sa) * dst + max(src, dst) }, { src, dst in src + dst - src * dst })
        case .multiply:
            return createColor(*, *)
        case .overlay:
            return createColor({src, dst in
                let first = 2 * src * dst
                if first < da {
                    return first
                } else {
                    return sa * dst - 2 * (da - src) * (sa - dst)
                }
            }, {src, dst in
                src + dst - src * dst
            })
        case .screen:
            return createColor({ (src: CGFloat, dst: CGFloat) in src + dst - src * dst }, { (src: CGFloat, dst: CGFloat) in src + dst - src * dst })
        case .src:
            return createColor({ src, _ in src }, { src, _ in src })
        case .srcAtop:
            return createColor({ src, dst in da * src + (1 - sa) * dst }, { _, dst in dst })
        case .srcIn:
            return createColor({ src, dst in src * dst }, { src, dst in src * dst })
        case .srcOut:
            return createColor({ src, dst in (1 - da ) * src }, { src, dst in (1 - dst) * src })
        case .srcOver:
            return createColor({ src, dst in src + (1 - sa ) * dst }, { src, dst in src + (1 - src) * dst })
        case .xor:
            return createColor({ (src: CGFloat, dst: CGFloat) in (1 - da) * src + (1 - sa) * dst}, { (src: CGFloat, dst: CGFloat) in (1 - dst) * src + (1 - src) * dst})
        }
    }