1/* 2 * Copyright 2011 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 "gm.h" 9#include "SkCanvas.h" 10#include "SkColorPriv.h" 11#include "SkColorSpace_Base.h" 12#include "SkShader.h" 13#include "SkSurface.h" 14 15#include "SkColorMatrixFilter.h" 16#include "SkGradientShader.h" 17 18static sk_sp<SkShader> make_opaque_color() { 19 return SkShader::MakeColorShader(0xFFFF0000); 20} 21 22static sk_sp<SkShader> make_alpha_color() { 23 return SkShader::MakeColorShader(0x80FF0000); 24} 25 26static sk_sp<SkColorFilter> make_cf_null() { 27 return nullptr; 28} 29 30static sk_sp<SkColorFilter> make_cf0() { 31 SkColorMatrix cm; 32 cm.setSaturation(0.75f); 33 return SkColorFilter::MakeMatrixFilterRowMajor255(cm.fMat); 34} 35 36static sk_sp<SkColorFilter> make_cf1() { 37 SkColorMatrix cm; 38 cm.setSaturation(0.75f); 39 auto a(SkColorFilter::MakeMatrixFilterRowMajor255(cm.fMat)); 40 // CreateComposedFilter will try to concat these two matrices, resulting in a single 41 // filter (which is good for speed). For this test, we want to force a real compose of 42 // these two, so our inner filter has a scale-up, which disables the optimization of 43 // combining the two matrices. 44 cm.setScale(1.1f, 0.9f, 1); 45 auto b(SkColorFilter::MakeMatrixFilterRowMajor255(cm.fMat)); 46 return SkColorFilter::MakeComposeFilter(a, b); 47} 48 49static sk_sp<SkColorFilter> make_cf2() { 50 return SkColorFilter::MakeModeFilter(0x8044CC88, SkBlendMode::kSrcATop); 51} 52 53static void draw_into_canvas(SkCanvas* canvas) { 54 const SkRect r = SkRect::MakeWH(50, 100); 55 sk_sp<SkShader> (*shaders[])() { make_opaque_color, make_alpha_color }; 56 sk_sp<SkColorFilter> (*filters[])() { make_cf_null, make_cf0, make_cf1, make_cf2 }; 57 58 SkPaint paint; 59 for (auto shProc : shaders) { 60 paint.setShader(shProc()); 61 for (auto cfProc : filters) { 62 paint.setColorFilter(cfProc()); 63 canvas->drawRect(r, paint); 64 canvas->translate(60, 0); 65 } 66 } 67} 68 69DEF_SIMPLE_GM(color4f, canvas, 1024, 260) { 70 canvas->translate(10, 10); 71 72 SkPaint bg; 73 // need the target to be opaque, so we can draw it to the screen 74 // even if it holds sRGB values. 75 bg.setColor(0xFFFFFFFF); 76 77 sk_sp<SkColorSpace> colorSpaces[]{ 78 nullptr, 79 SkColorSpace::MakeSRGB() 80 }; 81 for (auto colorSpace : colorSpaces) { 82 const SkImageInfo info = SkImageInfo::Make(1024, 100, kN32_SkColorType, kPremul_SkAlphaType, 83 colorSpace); 84 auto surface(SkSurface::MakeRaster(info)); 85 surface->getCanvas()->drawPaint(bg); 86 draw_into_canvas(surface->getCanvas()); 87 surface->draw(canvas, 0, 0, nullptr); 88 canvas->translate(0, 120); 89 } 90} 91 92/////////////////////////////////////////////////////////////////////////////////////////////////// 93#include "SkColorSpace.h" 94 95DEF_SIMPLE_GM(color4shader, canvas, 360, 480) { 96 canvas->translate(10, 10); 97 98 auto srgb = SkColorSpace::MakeSRGB(); 99 100 SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor); 101 // red -> blue, green -> red, blue -> green (sRGB) 102 mat.set3x3(0, 0, 1, 1, 0, 0, 0, 1, 0); 103 mat.postConcat(*as_CSB(srgb)->toXYZD50()); 104 105 const SkColor4f colors[] { 106 { 1, 0, 0, 1 }, 107 { 0, 1, 0, 1 }, 108 { 0, 0, 1, 1 }, 109 { 0.5, 0.5, 0.5, 1 }, 110 }; 111 112 SkPaint paint; 113 SkRect r = SkRect::MakeWH(100, 100); 114 115 for (const auto& c4 : colors) { 116 sk_sp<SkShader> shaders[] { 117 SkShader::MakeColorShader(c4, nullptr), 118 SkShader::MakeColorShader(c4, srgb), 119 SkShader::MakeColorShader(c4, 120 SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma, mat)), 121 }; 122 123 canvas->save(); 124 for (const auto& s : shaders) { 125 paint.setShader(s); 126 canvas->drawRect(r, paint); 127 canvas->translate(r.width() * 6 / 5, 0); 128 } 129 canvas->restore(); 130 canvas->translate(0, r.height() * 6 / 5); 131 } 132} 133