blob: 007caa3b4ec6832758e0183bb1015314a618fbf6 [file] [log] [blame]
reed@google.com83226972012-06-07 20:26:47 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8#include "Test.h"
9#include "SkTemplates.h"
10#include "SkShader.h"
11#include "SkColorShader.h"
12#include "SkEmptyShader.h"
13#include "SkGradientShader.h"
14
15struct GradRec {
16 int fColorCount;
17 const SkColor* fColors;
18 const SkScalar* fPos;
19 const SkPoint* fPoint; // 2
20 const SkScalar* fRadius; // 2
21 SkShader::TileMode fTileMode;
22
23 void gradCheck(skiatest::Reporter* reporter, SkShader* shader,
24 SkShader::GradientInfo* info,
25 SkShader::GradientType gt) const {
26 SkAutoTMalloc<SkColor> colorStorage(fColorCount);
27 SkAutoTMalloc<SkScalar> posStorage(fColorCount);
28
29 info->fColorCount = fColorCount;
30 info->fColors = colorStorage;
31 info->fColorOffsets = posStorage.get();
32 REPORTER_ASSERT(reporter, shader->asAGradient(info) == gt);
33
34 REPORTER_ASSERT(reporter, info->fColorCount == fColorCount);
35 REPORTER_ASSERT(reporter,
36 !memcmp(info->fColors, fColors, fColorCount * sizeof(SkColor)));
37 REPORTER_ASSERT(reporter,
38 !memcmp(info->fColorOffsets, fPos, fColorCount * sizeof(SkScalar)));
39 REPORTER_ASSERT(reporter, fTileMode == info->fTileMode);
40 }
41};
42
43
44static void none_gradproc(skiatest::Reporter* reporter, const GradRec& rec) {
45 SkAutoTUnref<SkShader> s(new SkEmptyShader);
46 REPORTER_ASSERT(reporter, SkShader::kNone_GradientType == s->asAGradient(NULL));
47}
48
49static void color_gradproc(skiatest::Reporter* reporter, const GradRec& rec) {
50 SkAutoTUnref<SkShader> s(new SkColorShader(rec.fColors[0]));
51 REPORTER_ASSERT(reporter, SkShader::kColor_GradientType == s->asAGradient(NULL));
52
53 SkShader::GradientInfo info;
54 info.fColorCount = 0;
55 s->asAGradient(&info);
56 REPORTER_ASSERT(reporter, 1 == info.fColorCount);
57}
58
59static void linear_gradproc(skiatest::Reporter* reporter, const GradRec& rec) {
60 SkAutoTUnref<SkShader> s(SkGradientShader::CreateLinear(rec.fPoint,
61 rec.fColors,
62 rec.fPos,
63 rec.fColorCount,
64 rec.fTileMode));
rmistry@google.comd6176b02012-08-23 18:14:13 +000065
reed@google.com83226972012-06-07 20:26:47 +000066 SkShader::GradientInfo info;
67 rec.gradCheck(reporter, s, &info, SkShader::kLinear_GradientType);
68 REPORTER_ASSERT(reporter, !memcmp(info.fPoint, rec.fPoint, 2 * sizeof(SkPoint)));
69}
70
71static void radial_gradproc(skiatest::Reporter* reporter, const GradRec& rec) {
72 SkAutoTUnref<SkShader> s(SkGradientShader::CreateRadial(rec.fPoint[0],
73 rec.fRadius[0],
74 rec.fColors,
75 rec.fPos,
76 rec.fColorCount,
77 rec.fTileMode));
rmistry@google.comd6176b02012-08-23 18:14:13 +000078
reed@google.com83226972012-06-07 20:26:47 +000079 SkShader::GradientInfo info;
80 rec.gradCheck(reporter, s, &info, SkShader::kRadial_GradientType);
81 REPORTER_ASSERT(reporter, info.fPoint[0] == rec.fPoint[0]);
82 REPORTER_ASSERT(reporter, info.fRadius[0] == rec.fRadius[0]);
83}
84
85static void radial2_gradproc(skiatest::Reporter* reporter, const GradRec& rec) {
86 SkAutoTUnref<SkShader> s(SkGradientShader::CreateTwoPointRadial(rec.fPoint[0],
87 rec.fRadius[0],
88 rec.fPoint[1],
89 rec.fRadius[1],
90 rec.fColors,
91 rec.fPos,
92 rec.fColorCount,
93 rec.fTileMode));
rmistry@google.comd6176b02012-08-23 18:14:13 +000094
reed@google.com83226972012-06-07 20:26:47 +000095 SkShader::GradientInfo info;
96 rec.gradCheck(reporter, s, &info, SkShader::kRadial2_GradientType);
97 REPORTER_ASSERT(reporter, !memcmp(info.fPoint, rec.fPoint, 2 * sizeof(SkPoint)));
98 REPORTER_ASSERT(reporter, !memcmp(info.fRadius, rec.fRadius, 2 * sizeof(SkScalar)));
99}
100
101static void sweep_gradproc(skiatest::Reporter* reporter, const GradRec& rec) {
102 SkAutoTUnref<SkShader> s(SkGradientShader::CreateSweep(rec.fPoint[0].fX,
103 rec.fPoint[0].fY,
104 rec.fColors,
105 rec.fPos,
106 rec.fColorCount));
rmistry@google.comd6176b02012-08-23 18:14:13 +0000107
reed@google.com83226972012-06-07 20:26:47 +0000108 SkShader::GradientInfo info;
109 rec.gradCheck(reporter, s, &info, SkShader::kSweep_GradientType);
110 REPORTER_ASSERT(reporter, info.fPoint[0] == rec.fPoint[0]);
111}
112
113static void conical_gradproc(skiatest::Reporter* reporter, const GradRec& rec) {
114 SkAutoTUnref<SkShader> s(SkGradientShader::CreateTwoPointConical(rec.fPoint[0],
115 rec.fRadius[0],
116 rec.fPoint[1],
117 rec.fRadius[1],
118 rec.fColors,
119 rec.fPos,
120 rec.fColorCount,
121 rec.fTileMode));
rmistry@google.comd6176b02012-08-23 18:14:13 +0000122
reed@google.com83226972012-06-07 20:26:47 +0000123 SkShader::GradientInfo info;
124 rec.gradCheck(reporter, s, &info, SkShader::kConical_GradientType);
125 REPORTER_ASSERT(reporter, !memcmp(info.fPoint, rec.fPoint, 2 * sizeof(SkPoint)));
126 REPORTER_ASSERT(reporter, !memcmp(info.fRadius, rec.fRadius, 2 * sizeof(SkScalar)));
127}
128
129typedef void (*GradProc)(skiatest::Reporter* reporter, const GradRec&);
130
131static void TestGradients(skiatest::Reporter* reporter) {
132 static const SkColor gColors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
133 static const SkScalar gPos[] = { 0, SK_ScalarHalf, SK_Scalar1 };
134 static const SkPoint gPts[] = {
135 { 0, 0 },
136 { SkIntToScalar(10), SkIntToScalar(20) }
137 };
138 static const SkScalar gRad[] = { SkIntToScalar(1), SkIntToScalar(2) };
139
140 GradRec rec;
141 rec.fColorCount = SK_ARRAY_COUNT(gColors);
142 rec.fColors = gColors;
143 rec.fPos = gPos;
144 rec.fPoint = gPts;
145 rec.fRadius = gRad;
146 rec.fTileMode = SkShader::kClamp_TileMode;
147
148 static const GradProc gProcs[] = {
149 none_gradproc,
150 color_gradproc,
151 linear_gradproc,
152 radial_gradproc,
153 radial2_gradproc,
154 sweep_gradproc,
155 conical_gradproc,
156 };
rmistry@google.comd6176b02012-08-23 18:14:13 +0000157
reed@google.com83226972012-06-07 20:26:47 +0000158 for (size_t i = 0; i < SK_ARRAY_COUNT(gProcs); ++i) {
159 gProcs[i](reporter, rec);
160 }
161}
162
163#include "TestClassDef.h"
164DEFINE_TESTCLASS("Gradients", TestGradientsClass, TestGradients)