/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/* Generated by tools/bookmaker from include/core/SkColor.h and docs/SkColor_Reference.bmh
   on 2018-06-14 13:13:34. Additional documentation and examples can be found at:
   https://skia.org/user/api/SkColor_Reference

   You may edit either file directly. Structural changes to public interfaces require
   editing both files. After editing docs/SkColor_Reference.bmh, run:
       bookmaker -b docs -i include/core/SkColor.h -p
   to create an updated version of this file.
 */

#ifndef SkColor_DEFINED
#define SkColor_DEFINED

#include "SkImageInfo.h"
#include "SkScalar.h"
#include "SkTypes.h"

/** \file SkColor.h

    Types, consts, functions, and macros for colors.
*/

/** 8-bit type for an alpha value. 255 is 100% opaque, zero is 100% transparent.
*/
typedef uint8_t SkAlpha;

/** 32-bit ARGB color value, unpremultiplied. Color components are always in
    a known order. This is different from SkPMColor, which has its bytes in a configuration
    dependent order, to match the format of kBGRA_8888_SkColorType bitmaps. SkColor
    is the type used to specify colors in SkPaint and in gradients.

    Color that is premultiplied has the same component values as color
    that is unpremultiplied if alpha is 255, fully opaque, although may have the
    component values in a different order.
*/
typedef uint32_t SkColor;

/** Returns color value from 8-bit component values. Asserts if SK_DEBUG is defined
    if a, r, g, or b exceed 255. Since color is unpremultiplied, a may be smaller
    than the largest of r, g, and b.

    @param a  amount of alpha, from fully transparent (0) to fully opaque (255)
    @param r  amount of red, from no red (0) to full red (255)
    @param g  amount of green, from no green (0) to full green (255)
    @param b  amount of blue, from no blue (0) to full blue (255)
    @return   color and alpha, unpremultiplied
*/
static constexpr inline SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
    return SkASSERT(a <= 255 && r <= 255 && g <= 255 && b <= 255),
           (a << 24) | (r << 16) | (g << 8) | (b << 0);
}

/** Returns color value from 8-bit component values, with alpha set
    fully opaque to 255.
*/
#define SkColorSetRGB(r, g, b)  SkColorSetARGB(0xFF, r, g, b)

/** Returns alpha byte from color value.
*/
#define SkColorGetA(color)      (((color) >> 24) & 0xFF)

/** Returns red component of color, from zero to 255.
*/
#define SkColorGetR(color)      (((color) >> 16) & 0xFF)

/** Returns green component of color, from zero to 255.
*/
#define SkColorGetG(color)      (((color) >>  8) & 0xFF)

/** Returns blue component of color, from zero to 255.
*/
#define SkColorGetB(color)      (((color) >>  0) & 0xFF)

/** Returns unpremultiplied color with red, blue, and green set from c; and alpha set
    from a. Alpha component of c is ignored and is replaced by a in result.

    @param c  packed RGB, eight bits per component
    @param a  alpha: transparent at zero, fully opaque at 255
    @return   color with transparency
*/
static constexpr inline SkColor SkColorSetA(SkColor c, U8CPU a) {
    return (c & 0x00FFFFFF) | (a << 24);
}

/** Represents fully transparent SkAlpha value. SkAlpha ranges from zero,
    fully transparent; to 255, fully opaque.
*/
constexpr SkAlpha SK_AlphaTRANSPARENT = 0x00;

/** Represents fully opaque SkAlpha value. SkAlpha ranges from zero,
    fully transparent; to 255, fully opaque.
*/
constexpr SkAlpha SK_AlphaOPAQUE      = 0xFF;

/** Represents fully transparent SkColor. May be used to initialize a destination
    containing a mask or a non-rectangular image.
*/
constexpr SkColor SK_ColorTRANSPARENT = SkColorSetARGB(0x00, 0x00, 0x00, 0x00);

/** Represents fully opaque black.
*/
constexpr SkColor SK_ColorBLACK       = SkColorSetARGB(0xFF, 0x00, 0x00, 0x00);

/** Represents fully opaque dark gray.
    Note that SVG dark gray is equivalent to 0xFFA9A9A9.
*/
constexpr SkColor SK_ColorDKGRAY      = SkColorSetARGB(0xFF, 0x44, 0x44, 0x44);

/** Represents fully opaque gray.
    Note that HTML gray is equivalent to 0xFF808080.
*/
constexpr SkColor SK_ColorGRAY        = SkColorSetARGB(0xFF, 0x88, 0x88, 0x88);

/** Represents fully opaque light gray. HTML silver is equivalent to 0xFFC0C0C0.
    Note that SVG light gray is equivalent to 0xFFD3D3D3.
*/
constexpr SkColor SK_ColorLTGRAY      = SkColorSetARGB(0xFF, 0xCC, 0xCC, 0xCC);

/** Represents fully opaque white.
*/
constexpr SkColor SK_ColorWHITE       = SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF);

/** Represents fully opaque red.
*/
constexpr SkColor SK_ColorRED         = SkColorSetARGB(0xFF, 0xFF, 0x00, 0x00);

/** Represents fully opaque green. HTML lime is equivalent.
    Note that HTML green is equivalent to 0xFF008000.
*/
constexpr SkColor SK_ColorGREEN       = SkColorSetARGB(0xFF, 0x00, 0xFF, 0x00);

/** Represents fully opaque blue.
*/
constexpr SkColor SK_ColorBLUE        = SkColorSetARGB(0xFF, 0x00, 0x00, 0xFF);

/** Represents fully opaque yellow.
*/
constexpr SkColor SK_ColorYELLOW      = SkColorSetARGB(0xFF, 0xFF, 0xFF, 0x00);

/** Represents fully opaque cyan. HTML aqua is equivalent.
*/
constexpr SkColor SK_ColorCYAN        = SkColorSetARGB(0xFF, 0x00, 0xFF, 0xFF);

/** Represents fully opaque magenta. HTML fuchsia is equivalent.
*/
constexpr SkColor SK_ColorMAGENTA     = SkColorSetARGB(0xFF, 0xFF, 0x00, 0xFF);

/** Converts RGB to its HSV components.
    hsv[0] contains hsv hue, a value from zero to less than 360.
    hsv[1] contains hsv saturation, a value from zero to one.
    hsv[2] contains hsv value, a value from zero to one.

    @param red    red component value from zero to 255
    @param green  green component value from zero to 255
    @param blue   blue component value from zero to 255
    @param hsv    three element array which holds the resulting HSV components
*/
SK_API void SkRGBToHSV(U8CPU red, U8CPU green, U8CPU blue, SkScalar hsv[3]);

/** Converts ARGB to its HSV components. Alpha in ARGB is ignored.
    hsv[0] contains hsv hue, and is assigned a value from zero to less than 360.
    hsv[1] contains hsv saturation, a value from zero to one.
    hsv[2] contains hsv value, a value from zero to one.

    @param color  ARGB color to convert
    @param hsv    three element array which holds the resulting HSV components
*/
static inline void SkColorToHSV(SkColor color, SkScalar hsv[3]) {
    SkRGBToHSV(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color), hsv);
}

/** Converts HSV components to an ARGB color. Alpha is passed through unchanged.
    hsv[0] represents hsv hue, an angle from zero to less than 360.
    hsv[1] represents hsv saturation, and varies from zero to one.
    hsv[2] represents hsv value, and varies from zero to one.

    Out of range hsv values are pinned.

    @param alpha  alpha component of the returned ARGB color
    @param hsv    three element array which holds the input HSV components
    @return       ARGB equivalent to HSV
*/
SK_API SkColor SkHSVToColor(U8CPU alpha, const SkScalar hsv[3]);

/** Converts HSV components to an ARGB color. Alpha is set to 255.
    hsv[0] represents hsv hue, an angle from zero to less than 360.
    hsv[1] represents hsv saturation, and varies from zero to one.
    hsv[2] represents hsv value, and varies from zero to one.

    Out of range hsv values are pinned.

    @param hsv  three element array which holds the input HSV components
    @return     RGB equivalent to HSV
*/
static inline SkColor SkHSVToColor(const SkScalar hsv[3]) {
    return SkHSVToColor(0xFF, hsv);
}

/** 32-bit ARGB color value, premultiplied. The byte order for this value is
    configuration dependent, matching the format of kBGRA_8888_SkColorType bitmaps.
    This is different from SkColor, which is unpremultiplied, and is always in the
    same byte order.
*/
typedef uint32_t SkPMColor;

/** Returns a SkPMColor value from unpremultiplied 8-bit component values.

    @param a  amount of alpha, from fully transparent (0) to fully opaque (255)
    @param r  amount of red, from no red (0) to full red (255)
    @param g  amount of green, from no green (0) to full green (255)
    @param b  amount of blue, from no blue (0) to full blue (255)
    @return   premultiplied color
*/
SK_API SkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);

/** Returns pmcolor closest to color c. Multiplies c RGB components by the c alpha,
    and arranges the bytes to match the format of kN32_SkColorType.

    @param c  unpremultiplied ARGB color
    @return   premultiplied color
*/
SK_API SkPMColor SkPreMultiplyColor(SkColor c);

/** \struct SkRGBA4f
    RGBA color value, holding four floating point components. Color components are always in
    a known order. kAT determines if the SkRGBA4f's R, G, and B components are premultiplied
    by alpha or not.

    Skia's public API always uses unpremultiplied colors, which can be stored as
    SkRGBA4f<kUnpremul_SkAlphaType>. For convenience, this type can also be referred to
    as SkColor4f.
*/
template <SkAlphaType kAT>
struct SkRGBA4f {
    float fR;  //!< red component
    float fG;  //!< green component
    float fB;  //!< blue component
    float fA;  //!< alpha component

    /** Compares SkRGBA4f with other, and returns true if all components are equal.

        @param other  SkRGBA4f to compare
        @return       true if SkRGBA4f equals other
    */
    bool operator==(const SkRGBA4f& other) const {
        return fA == other.fA && fR == other.fR && fG == other.fG && fB == other.fB;
    }

    /** Compares SkRGBA4f with other, and returns true if not all components are equal.

        @param other  SkRGBA4f to compare
        @return       true if SkRGBA4f is not equal to other
    */
    bool operator!=(const SkRGBA4f& other) const {
        return !(*this == other);
    }

    /** Returns SkRGBA4f multiplied by scale.

        @param scale  value to multiply by
        @return       SkRGBA4f as (fR * scale, fG * scale, fB * scale, fA * scale)
    */
    SkRGBA4f operator*(float scale) const {
        return { fR * scale, fG * scale, fB * scale, fA * scale };
    }

    /** Returns SkRGBA4f multiplied component-wise by scale.

        @param scale  SkRGBA4f to multiply by
        @return       SkRGBA4f as (fR * scale.fR, fG * scale.fG, fB * scale.fB, fA * scale.fA)
    */
    SkRGBA4f operator*(const SkRGBA4f& scale) const {
        return { fR * scale.fR, fG * scale.fG, fB * scale.fB, fA * scale.fA };
    }

    /** Returns a pointer to components of SkRGBA4f, for array access.

        @return       pointer to array [fR, fG, fB, fA]
    */
    const float* vec() const { return &fR; }

    /** Returns a pointer to components of SkRGBA4f, for array access.

        @return       pointer to array [fR, fG, fB, fA]
    */
    float* vec() { return &fR; }

    /** Returns one component. Asserts if index is out of range and SK_DEBUG is defined.

        @param index  one of: 0 (fR), 1 (fG), 2 (fB), 3 (fA)
        @return       value corresponding to index
    */
    float operator[](int index) const {
        SkASSERT(index >= 0 && index < 4);
        return this->vec()[index];
    }

    /** Returns one component. Asserts if index is out of range and SK_DEBUG is defined.

        @param index  one of: 0 (fR), 1 (fG), 2 (fB), 3 (fA)
        @return       value corresponding to index
    */
    float& operator[](int index) {
        SkASSERT(index >= 0 && index < 4);
        return this->vec()[index];
    }

    /** Returns true if SkRGBA4f is an opaque color. Asserts if fA is out of range and
        SK_DEBUG is defined.

        @return       true if SkRGBA4f is opaque
    */
    bool isOpaque() const {
        SkASSERT(fA <= 1.0f && fA >= 0.0f);
        return fA == 1.0f;
    }

    /** Returns closest SkRGBA4f to SkColor. Only allowed if SkRGBA4f is unpremultiplied.

        @param color   Color with Alpha, red, blue, and green components
        @return        SkColor as SkRGBA4f
    */
    static SkRGBA4f FromColor(SkColor color);  // impl. depends on kAT

    /** Returns closest SkColor to SkRGBA4f. Only allowed if SkRGBA4f is unpremultiplied.

        @return       color as SkColor
    */
    SkColor toSkColor() const;  // impl. depends on kAT

    /** Returns closest SkRGBA4f to SkPMColor. Only allowed if SkRGBA4f is premultiplied.

        @return        SkPMColor as SkRGBA4f
    */
    static SkRGBA4f FromPMColor(SkPMColor);  // impl. depends on kAT

    /** Returns SkRGBA4f premultiplied by alpha. Asserts at compile time if SkRGBA4f is
        already premultiplied.

        @return       premultiplied color
    */
    SkRGBA4f<kPremul_SkAlphaType> premul() const {
        static_assert(kAT == kUnpremul_SkAlphaType, "");
        return { fR * fA, fG * fA, fB * fA, fA };
    }

    /** Returns SkRGBA4f unpremultiplied by alpha. Asserts at compile time if SkRGBA4f is
        already unpremultiplied.

        @return       unpremultiplied color
    */
    SkRGBA4f<kUnpremul_SkAlphaType> unpremul() const {
        static_assert(kAT == kPremul_SkAlphaType, "");

        if (fA == 0.0f) {
            return { 0, 0, 0, 0 };
        } else {
            float invAlpha = 1 / fA;
            return { fR * invAlpha, fG * invAlpha, fB * invAlpha, fA };
        }
    }

    // This produces bytes in RGBA order (eg GrColor). Impl. is the same, regardless of kAT
    uint32_t toBytes_RGBA() const;
    static SkRGBA4f FromBytes_RGBA(uint32_t color);

    SkRGBA4f makeOpaque() const {
        return { fR, fG, fB, 1.0f };
    }
};

/** \struct SkColor4f
    RGBA color value, holding four floating point components. Color components are always in
    a known order, and are unpremultiplied.

    This is a specialization of SkRGBA4f. For details, @see SkRGBA4f.
*/
using SkColor4f = SkRGBA4f<kUnpremul_SkAlphaType>;

template <> SK_API SkColor4f SkColor4f::FromColor(SkColor);
template <> SK_API SkColor   SkColor4f::toSkColor() const;

#endif
