/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/shaders/SkColorShader.h"

#include "include/core/SkAlphaType.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkData.h"
#include "include/core/SkFlattenable.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkShader.h"
#include "include/private/SkFloatingPoint.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkColorSpaceXformSteps.h"
#include "src/core/SkEffectPriv.h"
#include "src/core/SkPicturePriv.h"
#include "src/core/SkRasterPipeline.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkWriteBuffer.h"
#include "src/shaders/SkShaderBase.h"

#include <utility>

namespace {

sk_sp<SkFlattenable> legacy_color4_create_proc(SkReadBuffer& buffer) {
    if (buffer.validate(buffer.isVersionLT(SkPicturePriv::Version::kCombineColorShaders))) {
        // Only SKPs older than this version should be referring to this create proc.
        SkColor4f color;
        sk_sp<SkColorSpace> colorSpace;
        buffer.readColor4f(&color);
        if (buffer.readBool()) {
            sk_sp<SkData> data = buffer.readByteArrayAsData();
            colorSpace = data ? SkColorSpace::Deserialize(data->data(), data->size()) : nullptr;
        }
        return SkShaders::Color(color, std::move(colorSpace));
    }

    return nullptr;
}

} // anonymous namespace

sk_sp<SkFlattenable> SkColorShader::CreateProc(SkReadBuffer& buffer) {
    if (buffer.isVersionLT(SkPicturePriv::Version::kCombineColorShaders)) {
        // Stored an 8-bit color only.
        return SkShaders::Color(buffer.readColor());
    } else {
        // Stores a floating-point color in sRGB.
        SkColor4f color;
        buffer.readColor4f(&color);
        return SkShaders::Color(color, SkColorSpace::MakeSRGB());
    }
}

void SkColorShader::flatten(SkWriteBuffer& buffer) const {
    buffer.writeColor4f(fColor);
}

bool SkColorShader::appendStages(const SkStageRec& rec, const SkShaders::MatrixRec&) const {
    SkColor4f color = fColor;
    SkColorSpaceXformSteps(sk_srgb_singleton(), kUnpremul_SkAlphaType,
                           rec.fDstCS,          kPremul_SkAlphaType).apply(color.vec());
    rec.fPipeline->appendConstantColor(rec.fAlloc, color.vec());
    return true;
}

/////////////////////////////////////////////////////////////////////////////////////////////////

void SkRegisterColorShaderFlattenable() {
    SK_REGISTER_FLATTENABLE(SkColorShader);
    SkFlattenable::Register("SkColorShader4", legacy_color4_create_proc);
}

namespace SkShaders {
sk_sp<SkShader> Color(SkColor color) {
    return Color(SkColor4f::FromColor(color), SkColorSpace::MakeSRGB());
}

sk_sp<SkShader> Color(const SkColor4f& color, sk_sp<SkColorSpace> space) {
    if (!SkIsFinite(color.vec(), 4)) {
        return nullptr;
    }

    // Convert to sRGB to simplify what must be stored, remaining unpremul until the final dst
    // color space is known during actual shading. Also pin the alpha to [0,1].
    SkColor4f srgb = color.pinAlpha();
    SkColorSpaceXformSteps(space.get(),         kUnpremul_SkAlphaType,
                           sk_srgb_singleton(), kUnpremul_SkAlphaType).apply(srgb.vec());

    return sk_make_sp<SkColorShader>(srgb);
}
}  // namespace SkShaders
