/*
 * Copyright 2021 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/effects/SkGradient.h"
#include "include/effects/SkImageFilters.h"

static void draw_bg_blur(SkCanvas* canvas, SkIRect rect, float sigma) {
    // First create an intermediate layer that has an opaque area that we blur with transparency
    // all around it. We want to make sure the transparency doesn't affect the blur of the opaque
    // content.
    auto outsetRect = SkRect::Make(rect).makeOutset(10, 10);
    canvas->saveLayer(outsetRect, nullptr);
    const SkColor4f colors[] = {SkColors::kRed, SkColors::kBlue, SkColors::kGreen};
    float cx = (rect.left() + rect.right() )/2.f;
    float cy = (rect.top()  + rect.bottom())/2.f;
    auto g = SkShaders::SweepGradient({cx, cy}, 0, 45,
                                      {{colors, {}, SkTileMode::kMirror}, {}});
    SkPaint paint;
    paint.setShader(std::move(g));
    canvas->drawRect(SkRect::Make(rect), paint);
    // Now do the bg-blur into another save-layer that should only read the opaque region.
    SkCanvas::SaveLayerRec rec;
    auto blur = SkImageFilters::Blur(sigma, sigma, SkTileMode::kClamp, nullptr, rect);
    rec.fBounds = &outsetRect;
    rec.fBackdrop = blur.get();
    canvas->saveLayer(rec);
    canvas->restore();
    canvas->restore();
}

DEF_SIMPLE_GM(crbug_1174354, canvas, 70, 250) {
    // The initial fix for crbug.com/1156805 had an issue where the border added to the downsampled
    // texture that was used as input to the blur could actually bring in transparency when there
    // wasn't any within the original src bounds. It was populated the border using a filtering draw
    // from the full res source that could read from outside the pixels surrounding the original src
    // bounds.
    draw_bg_blur(canvas, SkIRect::MakeXYWH(10,  10,  50, 50),  5);
    draw_bg_blur(canvas, SkIRect::MakeXYWH(10,  70,  50, 50), 15);
    draw_bg_blur(canvas, SkIRect::MakeXYWH(10, 130,  50, 50), 30);
    draw_bg_blur(canvas, SkIRect::MakeXYWH(10, 190, 50, 50),  70);
}
