/* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "include/core/SkBitmap.h" #include "include/core/SkCanvas.h" #include "include/core/SkShader.h" #include "include/core/SkSurface.h" #include "include/effects/SkGradientShader.h" #include "src/shaders/SkColorShader.h" #include "tests/Test.h" #include "tools/ToolUtils.h" static void test_bitmap(skiatest::Reporter* reporter) { SkImageInfo info = SkImageInfo::MakeN32Premul(2, 2); SkBitmap bmp; bmp.setInfo(info); // test 1: bitmap without pixel data auto shader = bmp.makeShader(SkSamplingOptions()); REPORTER_ASSERT(reporter, shader); REPORTER_ASSERT(reporter, !shader->isOpaque()); // From this point on, we have pixels bmp.allocPixels(info); // test 2: not opaque by default shader = bmp.makeShader(SkSamplingOptions()); REPORTER_ASSERT(reporter, shader); REPORTER_ASSERT(reporter, !shader->isOpaque()); // test 3: explicitly opaque bmp.setAlphaType(kOpaque_SkAlphaType); shader = bmp.makeShader(SkSamplingOptions()); REPORTER_ASSERT(reporter, shader); REPORTER_ASSERT(reporter, shader->isOpaque()); // test 4: explicitly not opaque bmp.setAlphaType(kPremul_SkAlphaType); shader = bmp.makeShader(SkSamplingOptions()); REPORTER_ASSERT(reporter, shader); REPORTER_ASSERT(reporter, !shader->isOpaque()); } static void test_gradient(skiatest::Reporter* reporter) { SkPoint pts[2]; pts[0].iset(0, 0); pts[1].iset(1, 0); SkColor colors[2]; SkScalar pos[2] = {SkIntToScalar(0), SkIntToScalar(1)}; int count = 2; SkTileMode mode = SkTileMode::kClamp; // test 1: all opaque colors[0] = SkColorSetARGB(0xFF, 0, 0, 0); colors[1] = SkColorSetARGB(0xFF, 0, 0, 0); auto grad = SkGradientShader::MakeLinear(pts, colors, pos, count, mode); REPORTER_ASSERT(reporter, grad); REPORTER_ASSERT(reporter, grad->isOpaque()); // test 2: all 0 alpha colors[0] = SkColorSetARGB(0, 0, 0, 0); colors[1] = SkColorSetARGB(0, 0, 0, 0); grad = SkGradientShader::MakeLinear(pts, colors, pos, count, mode); REPORTER_ASSERT(reporter, grad); REPORTER_ASSERT(reporter, !grad->isOpaque()); // test 3: one opaque, one transparent colors[0] = SkColorSetARGB(0xFF, 0, 0, 0); colors[1] = SkColorSetARGB(0x40, 0, 0, 0); grad = SkGradientShader::MakeLinear(pts, colors, pos, count, mode); REPORTER_ASSERT(reporter, grad); REPORTER_ASSERT(reporter, !grad->isOpaque()); // test 4: test 3, swapped colors[0] = SkColorSetARGB(0x40, 0, 0, 0); colors[1] = SkColorSetARGB(0xFF, 0, 0, 0); grad = SkGradientShader::MakeLinear(pts, colors, pos, count, mode); REPORTER_ASSERT(reporter, grad); REPORTER_ASSERT(reporter, !grad->isOpaque()); } static void test_color(skiatest::Reporter* reporter) { SkColorShader colorShader1(SkColorSetARGB(0,0,0,0)); REPORTER_ASSERT(reporter, !colorShader1.isOpaque()); SkColorShader colorShader2(SkColorSetARGB(0xFF,0,0,0)); REPORTER_ASSERT(reporter, colorShader2.isOpaque()); SkColorShader colorShader3(SkColorSetARGB(0x7F,0,0,0)); REPORTER_ASSERT(reporter, !colorShader3.isOpaque()); } DEF_TEST(ShaderOpacity, reporter) { test_gradient(reporter); test_color(reporter); test_bitmap(reporter); } #ifdef SK_SUPPORT_LEGACY_IMPLICIT_FILTERQUALITY DEF_TEST(image_shader_filtering, reporter) { auto make_checker_img = [](int w, int h) { auto info = SkImageInfo::Make(w, h, kRGBA_8888_SkColorType, kOpaque_SkAlphaType); auto surf = SkSurface::MakeRaster(info); ToolUtils::draw_checkerboard(surf->getCanvas(), SK_ColorRED, SK_ColorBLUE, 2); return surf->makeImageSnapshot(); }; auto img = make_checker_img(4, 4); const SkFilterQuality quals[] = { kNone_SkFilterQuality, kLow_SkFilterQuality, kMedium_SkFilterQuality, kHigh_SkFilterQuality, }; const SkScalar scales[] = { 3.0f, 1.0f, 0.5f, 0.25f, 0.125f }; auto make_img = [&](const SkPaint& paint) { auto info = SkImageInfo::Make(70, 70, kRGBA_8888_SkColorType, kPremul_SkAlphaType); auto surf = SkSurface::MakeRaster(info); auto canvas = surf->getCanvas(); canvas->scale(1.06f, 1.06f); // nicely exaggerates noise when not filtering canvas->drawRect({0, 0, 64, 64}, paint); return surf->makeImageSnapshot(); }; SkPaint paint; for (auto q : quals) { for (auto scale : scales) { SkMatrix m = SkMatrix::Scale(scale, scale); paint.setFilterQuality(kNone_SkFilterQuality); // this setting should be ignored paint.setShader(img->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, SkSamplingOptions(q), &m)); auto img0 = make_img(paint); paint.setFilterQuality(q); // this should (still) be ignored auto img1 = make_img(paint); // make legacy form of shader, relying on the paint's filter-quality (q) paint.setShader(img->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, &m)); auto img2 = make_img(paint); REPORTER_ASSERT(reporter, ToolUtils::equal_pixels(img0.get(), img1.get())); REPORTER_ASSERT(reporter, ToolUtils::equal_pixels(img0.get(), img2.get())); } } } #endif