1/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkBitmapProcShader.h"
9#include "SkColor.h"
10#include "SkColorMatrixFilter.h"
11#include "SkGradientShader.h"
12#include "SkImage.h"
13#include "SkPM4f.h"
14#include "SkShader.h"
15
16#include "Test.h"
17#include "SkRandom.h"
18
19const float kTolerance = 1.0f / (1 << 20);
20
21static bool nearly_equal(float a, float b, float tol = kTolerance) {
22    SkASSERT(tol >= 0);
23    return fabsf(a - b) <= tol;
24}
25
26DEF_TEST(SkColor4f_FromColor, reporter) {
27    const struct {
28        SkColor     fC;
29        SkColor4f   fC4;
30    } recs[] = {
31        { SK_ColorBLACK, { 0, 0, 0, 1 } },
32        { SK_ColorWHITE, { 1, 1, 1, 1 } },
33        { SK_ColorRED,   { 1, 0, 0, 1 } },
34        { SK_ColorGREEN, { 0, 1, 0, 1 } },
35        { SK_ColorBLUE,  { 0, 0, 1, 1 } },
36        { 0,             { 0, 0, 0, 0 } },
37    };
38
39    for (const auto& r : recs) {
40        SkColor4f c4 = SkColor4f::FromColor(r.fC);
41        REPORTER_ASSERT(reporter, c4 == r.fC4);
42    }
43}
44
45DEF_TEST(Color4f_premul, reporter) {
46    SkRandom rand;
47
48    for (int i = 0; i < 1000000; ++i) {
49        // First just test opaque colors, so that the premul should be exact
50        SkColor4f c4 {
51            rand.nextUScalar1(), rand.nextUScalar1(), rand.nextUScalar1(), 1
52        };
53        SkPM4f pm4 = c4.premul();
54        REPORTER_ASSERT(reporter, pm4.a() == c4.fA);
55        REPORTER_ASSERT(reporter, pm4.r() == c4.fA * c4.fR);
56        REPORTER_ASSERT(reporter, pm4.g() == c4.fA * c4.fG);
57        REPORTER_ASSERT(reporter, pm4.b() == c4.fA * c4.fB);
58
59        // We compare with a tolerance, in case our premul multiply is implemented at slightly
60        // different precision than the test code.
61        c4.fA = rand.nextUScalar1();
62        pm4 = c4.premul();
63        REPORTER_ASSERT(reporter, pm4.fVec[SK_A_INDEX] == c4.fA);
64        REPORTER_ASSERT(reporter, nearly_equal(pm4.r(), c4.fA * c4.fR));
65        REPORTER_ASSERT(reporter, nearly_equal(pm4.g(), c4.fA * c4.fG));
66        REPORTER_ASSERT(reporter, nearly_equal(pm4.b(), c4.fA * c4.fB));
67    }
68}
69