* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef Sk4fGradientPriv_DEFINED
#define Sk4fGradientPriv_DEFINED
#include "include/core/SkColor.h"
#include "include/core/SkImageInfo.h"
#include "include/private/SkColorData.h"
#include "include/private/SkHalf.h"
#include "include/private/SkNx.h"
#include "src/core/SkUtils.h"
namespace {
enum class ApplyPremul { True, False };
template <ApplyPremul>
struct PremulTraits;
template <>
struct PremulTraits<ApplyPremul::False> {
static Sk4f apply(const Sk4f& c) { return c; }
};
template <>
struct PremulTraits<ApplyPremul::True> {
static Sk4f apply(const Sk4f& c) {
const float alpha = c[3];
return c * Sk4f(alpha, alpha, alpha, 1);
}
};
template <ApplyPremul premul>
struct DstTraits {
using PM = PremulTraits<premul>;
static Sk4f load(const SkPMColor4f& c) {
Sk4f c4f = swizzle_rb_if_bgra(Sk4f::Load(c.vec()));
return premul == ApplyPremul::False
? c4f * Sk4f(255)
: c4f;
}
static void store(const Sk4f& c, SkPMColor* dst, const Sk4f& bias) {
if (premul == ApplyPremul::False) {
SkNx_cast<uint8_t>(c).store(dst);
} else {
*dst = Sk4f_toL32(PM::apply(c) + bias);
}
}
static void store(const Sk4f& c, SkPMColor* dst, int n) {
SkPMColor pmc;
store(c, &pmc, Sk4f(0));
sk_memset32(dst, pmc, n);
}
static void store4x(const Sk4f& c0, const Sk4f& c1,
const Sk4f& c2, const Sk4f& c3,
SkPMColor* dst,
const Sk4f& bias0,
const Sk4f& bias1) {
if (premul == ApplyPremul::False) {
Sk4f_ToBytes((uint8_t*)dst, c0, c1, c2, c3);
} else {
store(c0, dst + 0, bias0);
store(c1, dst + 1, bias1);
store(c2, dst + 2, bias0);
store(c3, dst + 3, bias1);
}
}
static Sk4f pre_lerp_bias(const Sk4f& bias) {
return premul == ApplyPremul::False ? bias : 0;
}
};
}
#endif