static void test_layerDrawLooper(skiatest::Reporter* reporter, sk_sp<SkMaskFilter> mf, SkScalar sigma, SkBlurStyle style, SkBlurQuality quality, bool expectSuccess) { SkLayerDrawLooper::LayerInfo info; SkLayerDrawLooper::Builder builder; // 1 layer is too few make_noop_layer(&builder); test_looper(reporter, builder.detach(), sigma, style, quality, false); // 2 layers is good, but need blur make_noop_layer(&builder); make_noop_layer(&builder); test_looper(reporter, builder.detach(), sigma, style, quality, false); // 2 layers is just right make_noop_layer(&builder); make_blur_layer(&builder, mf); test_looper(reporter, builder.detach(), sigma, style, quality, expectSuccess); // 3 layers is too many make_noop_layer(&builder); make_blur_layer(&builder, mf); make_noop_layer(&builder); test_looper(reporter, builder.detach(), sigma, style, quality, false); }
DEF_TEST(Paint_copy, reporter) { SkPaint paint; // set a few member variables paint.setStyle(SkPaint::kStrokeAndFill_Style); paint.setTextAlign(SkPaint::kLeft_Align); paint.setStrokeWidth(SkIntToScalar(2)); // set a few pointers SkLayerDrawLooper::Builder looperBuilder; paint.setLooper(looperBuilder.detach()); paint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, SkBlurMask::ConvertRadiusToSigma(1))); // copy the paint using the copy constructor and check they are the same SkPaint copiedPaint = paint; REPORTER_ASSERT(reporter, paint == copiedPaint); // copy the paint using the equal operator and check they are the same copiedPaint = paint; REPORTER_ASSERT(reporter, paint == copiedPaint); // clean the paint and check they are back to their initial states SkPaint cleanPaint; paint.reset(); copiedPaint.reset(); REPORTER_ASSERT(reporter, cleanPaint == paint); REPORTER_ASSERT(reporter, cleanPaint == copiedPaint); }
void init() { if (fLooper) return; constexpr struct { SkColor fColor; SkPaint::Style fStyle; SkScalar fWidth; SkScalar fOffset; SkScalar fBlur; } gParams[] = { { SK_ColorWHITE, SkPaint::kStroke_Style, SkIntToScalar(1)*3/4, 0, 0 }, { SK_ColorRED, SkPaint::kStroke_Style, SkIntToScalar(4), 0, 0 }, { SK_ColorBLUE, SkPaint::kFill_Style, 0, 0, 0 }, { 0x88000000, SkPaint::kFill_Style, 0, SkIntToScalar(10), SkIntToScalar(3) } }; SkLayerDrawLooper::Builder looperBuilder; SkLayerDrawLooper::LayerInfo info; info.fPaintBits = SkLayerDrawLooper::kStyle_Bit | SkLayerDrawLooper::kMaskFilter_Bit; info.fColorMode = SkBlendMode::kSrc; for (size_t i = 0; i < SK_ARRAY_COUNT(gParams); i++) { info.fOffset.set(gParams[i].fOffset, gParams[i].fOffset); SkPaint* paint = looperBuilder.addLayer(info); paint->setColor(gParams[i].fColor); paint->setStyle(gParams[i].fStyle); paint->setStrokeWidth(gParams[i].fWidth); if (gParams[i].fBlur > 0) { paint->setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, SkBlurMask::ConvertRadiusToSigma(gParams[i].fBlur))); } } fLooper = looperBuilder.detach(); }
sk_sp<SkDrawLooper> createLooper(SkScalar xOff, SkScalar sigma) { SkLayerDrawLooper::Builder looperBuilder; //----------------------------------------------- SkLayerDrawLooper::LayerInfo info; // TODO: add a color filter to better match what is seen in the wild info.fPaintBits = /* SkLayerDrawLooper::kColorFilter_Bit |*/ SkLayerDrawLooper::kMaskFilter_Bit; info.fColorMode = SkXfermode::kDst_Mode; info.fOffset.set(xOff, 0); info.fPostTranslate = false; SkPaint* paint = looperBuilder.addLayer(info); paint->setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, sigma, SkBlurMaskFilter::kHighQuality_BlurFlag)); //----------------------------------------------- info.fPaintBits = 0; info.fOffset.set(0, 0); paint = looperBuilder.addLayer(info); return looperBuilder.detach(); }
void onDraw(int loops, SkCanvas* canvas) override { SkLayerDrawLooper::Builder looperBuilder; { SkLayerDrawLooper::LayerInfo info; info.fPaintBits = SkLayerDrawLooper::kMaskFilter_Bit | SkLayerDrawLooper::kColorFilter_Bit; info.fColorMode = (SK_XFERMODE_MODE_PARAM)SkBlendMode::kSrc; info.fOffset = SkPoint::Make(SkIntToScalar(-1), SkIntToScalar(0)); info.fPostTranslate = false; SkPaint* paint = looperBuilder.addLayerOnTop(info); paint->setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, SkBlurMask::ConvertRadiusToSigma(0.5), SkBlurMaskFilter::kHighQuality_BlurFlag)); paint->setColorFilter(SkColorFilter::MakeModeFilter(SK_ColorLTGRAY, SkBlendMode::kSrcIn)); paint->setColor(SK_ColorGRAY); } { SkLayerDrawLooper::LayerInfo info; looperBuilder.addLayerOnTop(info); } SkPaint dullPaint; dullPaint.setAntiAlias(true); SkPaint loopedPaint; loopedPaint.setLooper(looperBuilder.detach()); loopedPaint.setAntiAlias(true); loopedPaint.setColor(SK_ColorCYAN); for (int i = 0; i < loops; i++) { canvas->drawRect(fRRect.rect(), dullPaint); canvas->drawRRect(fRRect, loopedPaint); } }
// Create a 1-tier drawlooper sk_sp<SkDrawLooper> create1Looper(SkScalar xOff, SkScalar yOff, SkColor color) { SkLayerDrawLooper::Builder looperBuilder; SkLayerDrawLooper::LayerInfo info; info.fPaintBits = SkLayerDrawLooper::kColorFilter_Bit | SkLayerDrawLooper::kMaskFilter_Bit; info.fColorMode = (SK_XFERMODE_MODE_PARAM)SkBlendMode::kSrc; info.fOffset.set(xOff, yOff); info.fPostTranslate = false; SkPaint* paint = looperBuilder.addLayer(info); paint->setMaskFilter(MakeBlur()); paint->setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kSrcIn)); return looperBuilder.detach(); }
// Create a 1-tier drawlooper sk_sp<SkDrawLooper> create1Looper(SkScalar xOff, SkScalar yOff, SkColor color) { SkLayerDrawLooper::Builder looperBuilder; SkLayerDrawLooper::LayerInfo info; info.fPaintBits = SkLayerDrawLooper::kColorFilter_Bit | SkLayerDrawLooper::kMaskFilter_Bit; info.fColorMode = SkXfermode::kSrc_Mode; info.fOffset.set(xOff, yOff); info.fPostTranslate = false; SkPaint* paint = looperBuilder.addLayer(info); paint->setMaskFilter(this->createBlur())->unref(); paint->setColorFilter(SkColorFilter::MakeModeFilter(color, SkXfermode::kSrcIn_Mode)); return looperBuilder.detach(); }
// Create a 4-tier draw looper sk_sp<SkDrawLooper> create4Looper(SkScalar xOff, SkScalar yOff) { SkLayerDrawLooper::Builder looperBuilder; SkLayerDrawLooper::LayerInfo info; info.fPaintBits = SkLayerDrawLooper::kColorFilter_Bit | SkLayerDrawLooper::kMaskFilter_Bit; info.fColorMode = (SK_XFERMODE_MODE_PARAM)SkBlendMode::kSrc; info.fPostTranslate = false; SkPaint* paint; for (int i = 3; i >= 0; --i) { info.fOffset.set(xOff+gBlurOffsets[i].fX, yOff+gBlurOffsets[i].fY); paint = looperBuilder.addLayer(info); paint->setMaskFilter(MakeBlur()); paint->setColorFilter(SkColorFilter::MakeModeFilter(gColors[i], SkBlendMode::kSrcIn)); } return looperBuilder.detach(); }
static void test_backToFront(skiatest::Reporter* reporter) { SkLayerDrawLooper::Builder looperBuilder; SkLayerDrawLooper::LayerInfo layerInfo; // Add the back layer, with the defaults. (void)looperBuilder.addLayerOnTop(layerInfo); // Add the front layer, with some layer info set. layerInfo.fOffset.set(10.0f, 20.0f); layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit; SkPaint* layerPaint = looperBuilder.addLayerOnTop(layerInfo); layerPaint->setBlendMode(SkBlendMode::kSrc); FakeDevice device; SkCanvas canvas(&device); SkPaint paint; auto looper(looperBuilder.detach()); SkArenaAlloc alloc{48}; SkDrawLooper::Context* context = looper->makeContext(&canvas, &alloc); // The back layer should come first. REPORTER_ASSERT(reporter, context->next(&canvas, &paint)); REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrcOver); canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX()); REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY()); paint.reset(); // Then the front layer. REPORTER_ASSERT(reporter, context->next(&canvas, &paint)); REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrc); canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX()); REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY()); // Only two layers were added, so that should be the end. REPORTER_ASSERT(reporter, !context->next(&canvas, &paint)); }
// Create a 4-tier draw looper sk_sp<SkDrawLooper> create4Looper(SkScalar xOff, SkScalar yOff) { SkLayerDrawLooper::Builder looperBuilder; SkLayerDrawLooper::LayerInfo info; info.fPaintBits = SkLayerDrawLooper::kColorFilter_Bit | SkLayerDrawLooper::kMaskFilter_Bit; info.fColorMode = SkXfermode::kSrc_Mode; info.fPostTranslate = false; SkPaint* paint; for (int i = 3; i >= 0; --i) { info.fOffset.set(xOff+gBlurOffsets[i].fX, yOff+gBlurOffsets[i].fY); paint = looperBuilder.addLayer(info); paint->setMaskFilter(this->createBlur())->unref(); SkColorFilter* cf = SkColorFilter::CreateModeFilter(gColors[i], SkXfermode::kSrcIn_Mode); paint->setColorFilter(cf)->unref(); } return looperBuilder.detach(); }
sk_sp<SkDrawLooper> SkBlurDrawLooper::Make(SkColor color, SkScalar sigma, SkScalar dx, SkScalar dy) { sk_sp<SkMaskFilter> blur = nullptr; if (sigma > 0.0f) { blur = SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, sigma, true); } SkLayerDrawLooper::Builder builder; // First layer SkLayerDrawLooper::LayerInfo defaultLayer; builder.addLayer(defaultLayer); // Blur layer SkLayerDrawLooper::LayerInfo blurInfo; blurInfo.fColorMode = SkBlendMode::kSrc; blurInfo.fPaintBits = SkLayerDrawLooper::kMaskFilter_Bit; blurInfo.fOffset = SkVector::Make(dx, dy); SkPaint* paint = builder.addLayer(blurInfo); paint->setMaskFilter(std::move(blur)); paint->setColor(color); return builder.detach(); }
static sk_sp<SkDrawLooper> setupLooper(SkLayerDrawLooper::BitFlags bits, LooperProc proc, const LooperSettings settings[], size_t size) { SkLayerDrawLooper::Builder looperBuilder; SkLayerDrawLooper::LayerInfo info; info.fPaintBits = bits; info.fColorMode = (SK_XFERMODE_MODE_PARAM)SkBlendMode::kSrc; for (size_t i = 0; i < size; i++) { info.fOffset.set(settings[i].fOffset, settings[i].fOffset); SkPaint* paint = looperBuilder.addLayer(info); paint->setBlendMode(settings[i].fMode); paint->setColor(settings[i].fColor); paint->setStyle(settings[i].fStyle); paint->setStrokeWidth(settings[i].fWidth); if (settings[i].fEffect) { (*proc)(paint); } } return looperBuilder.detach(); }