1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2016 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "gm.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "sk_tool_utils.h"
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBlurMaskFilter.h"
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRRect.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic SkRect offset_center_to(const SkIRect& src, SkScalar x, SkScalar y) {
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar halfW = 0.5f * src.width();
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar halfH = 0.5f * src.height();
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkRect::MakeLTRB(x - halfW, y - halfH, x + halfW, y + halfH);
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void draw_rrect(SkCanvas* canvas, const SkRRect& rr, const SkRRect& occRR) {
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkScalar kBlurSigma = 5.0f;
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRect occRect;
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkColor strokeColor;
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkRect occRect1 = sk_tool_utils::compute_central_occluder(occRR);
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkRect occRect2 = sk_tool_utils::compute_widest_occluder(occRR);
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkRect occRect3 = sk_tool_utils::compute_tallest_occluder(occRR);
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar area1 = occRect1.width() * occRect1.height();
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar area2 = occRect2.width() * occRect2.height();
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar area3 = occRect3.width() * occRect3.height();
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (area1 >= area2 && area1 >= area3) {
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            strokeColor = SK_ColorRED;
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            occRect = occRect1;
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else if (area2 > area3) {
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            strokeColor = SK_ColorYELLOW;
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            occRect = occRect2;
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else {
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            strokeColor = SK_ColorCYAN;
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            occRect = occRect3;
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // draw the blur
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint paint;
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, kBlurSigma, occRect));
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawRRect(rr, paint);
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // draw the stroked geometry of the full occluder
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint stroke;
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    stroke.setStyle(SkPaint::kStroke_Style);
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    stroke.setColor(SK_ColorBLUE);
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawRRect(occRR, stroke);
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // draw the geometry of the occluding rect
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    stroke.setColor(strokeColor);
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawRect(occRect, stroke);
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void draw_45(SkCanvas* canvas, SkRRect::Corner corner,
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkScalar dist, const SkPoint& center) {
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRRect::Corner left = SkRRect::kUpperLeft_Corner, right = SkRRect::kUpperLeft_Corner;
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkVector dir = { 0, 0 };
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    constexpr SkScalar kSize = 64.0f / SK_ScalarSqrt2;
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    switch (corner) {
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    case SkRRect::kUpperLeft_Corner:
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        left = SkRRect::kUpperRight_Corner;
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        right = SkRRect::kLowerLeft_Corner;
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        dir.set(-SK_ScalarRoot2Over2, -SK_ScalarRoot2Over2);
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        break;
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    case SkRRect::kUpperRight_Corner:
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        left = SkRRect::kUpperLeft_Corner;
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        right = SkRRect::kLowerRight_Corner;
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        dir.set(SK_ScalarRoot2Over2, -SK_ScalarRoot2Over2);
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        break;
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    case SkRRect::kLowerRight_Corner:
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        left = SkRRect::kLowerLeft_Corner;
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        right = SkRRect::kUpperRight_Corner;
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        dir.set(SK_ScalarRoot2Over2, SK_ScalarRoot2Over2);
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        break;
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    case SkRRect::kLowerLeft_Corner:
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        left = SkRRect::kLowerRight_Corner;
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        right = SkRRect::kUpperLeft_Corner;
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        dir.set(-SK_ScalarRoot2Over2, SK_ScalarRoot2Over2);
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        break;
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    default:
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SK_ABORT("Invalid shape.");
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRect r = SkRect::MakeWH(kSize, kSize);
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // UL, UR, LR, LL
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkVector radii[4] = { { 0.0f, 0.0f }, { 0.0f, 0.0f }, { 0.0f, 0.0f }, { 0.0f, 0.0f } };
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    radii[left] = SkVector::Make(kSize, kSize);
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    radii[right] = SkVector::Make(kSize, kSize);
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRRect rr;
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rr.setRectRadii(
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            offset_center_to(r.roundOut(), center.fX + dist*dir.fX, center.fY + dist*dir.fY),
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            radii);
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRRect occRR;
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    dist -= 10.0f;
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    occRR.setRectRadii(
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            offset_center_to(r.roundOut(), center.fX + dist*dir.fX, center.fY + dist*dir.fY),
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            radii);
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    draw_rrect(canvas, rr, occRR);
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void draw_45_simple(SkCanvas* canvas, const SkVector& v,
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                           SkScalar dist, const SkPoint& center) {
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIRect r = SkIRect::MakeWH(64, 64);
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRRect rr = SkRRect::MakeRectXY(
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY),
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            8, 8);
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    dist -= 10.0f;
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRRect occRR = SkRRect::MakeRectXY(
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY),
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            8, 8);
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    draw_rrect(canvas, rr, occRR);
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void draw_90(SkCanvas* canvas, const SkVector& v, SkScalar dist, const SkPoint& center) {
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    constexpr int kWidth = 25;
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIRect r;
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (fabs(v.fX) < fabs(v.fY)) {
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r = SkIRect::MakeWH(kWidth, 64);
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    } else {
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r = SkIRect::MakeWH(64, kWidth);
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRRect rr = SkRRect::MakeOval(
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY));
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    dist -= 10.0f;
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRRect occRR = SkRRect::MakeOval(
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY));
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    draw_rrect(canvas, rr, occRR);
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void draw_90_simple(SkCanvas* canvas, const SkVector& v,
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                           SkScalar dist, const SkPoint& center) {
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    constexpr int kLength = 128;
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // The width needs to be larger than 2*3*blurRadii+2*cornerRadius for the analytic
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // RRect blur to kick in
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    constexpr int kWidth = 47;
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIRect r;
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (fabs(v.fX) < fabs(v.fY)) {
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r = SkIRect::MakeWH(kLength, kWidth);
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    } else {
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r = SkIRect::MakeWH(kWidth, kLength);
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRRect rr = SkRRect::MakeRectXY(
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY),
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            8, 8);
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    dist -= 10.0f;
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRRect occRR = SkRRect::MakeRectXY(
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY),
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            8, 8);
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    draw_rrect(canvas, rr, occRR);
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void draw_30_60(SkCanvas* canvas, SkRRect::Corner corner, const SkVector& v,
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                       SkScalar dist, const SkPoint& center) {
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRRect::Corner left = SkRRect::kUpperLeft_Corner, right = SkRRect::kUpperLeft_Corner;
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    constexpr int kLength = 64;
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    constexpr int kWidth = 30;
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    switch (corner) {
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    case SkRRect::kUpperLeft_Corner:
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        left = SkRRect::kUpperRight_Corner;
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        right = SkRRect::kLowerLeft_Corner;
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        break;
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    case SkRRect::kUpperRight_Corner:
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        left = SkRRect::kUpperLeft_Corner;
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        right = SkRRect::kLowerRight_Corner;
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        break;
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    case SkRRect::kLowerRight_Corner:
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        left = SkRRect::kLowerLeft_Corner;
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        right = SkRRect::kUpperRight_Corner;
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        break;
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    case SkRRect::kLowerLeft_Corner:
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        left = SkRRect::kLowerRight_Corner;
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        right = SkRRect::kUpperLeft_Corner;
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        break;
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    default:
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SK_ABORT("Invalid shape.");
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIRect r;
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (fabs(v.fX) < fabs(v.fY)) {
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r = SkIRect::MakeWH(kLength, kWidth);
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    } else {
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r = SkIRect::MakeWH(kWidth, kLength);
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // UL, UR, LR, LL
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkVector radii[4] = { { 0.0f, 0.0f }, { 0.0f, 0.0f }, { 0.0f, 0.0f }, { 0.0f, 0.0f } };
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    radii[left] = SkVector::Make(SkIntToScalar(kWidth), SkIntToScalar(kWidth));
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    radii[right] = SkVector::Make(SkIntToScalar(kWidth), SkIntToScalar(kWidth));
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRRect rr;
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rr.setRectRadii(offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY), radii);
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    dist -= 10.0f;
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRRect occRR;
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    occRR.setRectRadii(offset_center_to(r, center.fX + dist*v.fX, center.fY + dist*v.fY), radii);
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    draw_rrect(canvas, rr, occRR);
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotnamespace skiagm {
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass OccludedRRectBlurGM : public GM {
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    OccludedRRectBlurGM() {
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString onShortName() override {
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkString("occludedrrectblur");
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkISize onISize() override {
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkISize::Make(kWidth, kHeight);
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onDraw(SkCanvas* canvas) override {
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SkPoint center = SkPoint::Make(kWidth/2, kHeight/2);
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // outer-most big RR
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        {
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkIRect r = SkIRect::MakeWH(420, 420);
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkRRect rr = SkRRect::MakeRectXY(offset_center_to(r, center.fX, center.fY), 64, 64);
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            draw_rrect(canvas, rr, rr);
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if 1
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // TODO: remove this. Until we actually start skipping the middle draw we need this
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // to provide contrast
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkPaint temp;
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            temp.setColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            r.inset(32, 32);
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->drawRect(offset_center_to(r, center.fX, center.fY), temp);
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // center circle
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        {
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkIRect r = SkIRect::MakeWH(32, 32);
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkRRect rr = SkRRect::MakeOval(offset_center_to(r, center.fX, center.fY));
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            draw_rrect(canvas, rr, rr);
263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_45(canvas, SkRRect::kUpperLeft_Corner, 64, center);
266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_45(canvas, SkRRect::kUpperRight_Corner, 64, center);
267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_45(canvas, SkRRect::kLowerRight_Corner, 64, center);
268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_45(canvas, SkRRect::kLowerLeft_Corner, 64, center);
269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_90(canvas, SkVector::Make(-1.0f, 0.0f), 64, center);
271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_90(canvas, SkVector::Make(0.0f, -1.0f), 64, center);
272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_90(canvas, SkVector::Make(1.0f, 0.0f), 64, center);
273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_90(canvas, SkVector::Make(0.0f, 1.0f), 64, center);
274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        constexpr SkScalar kRoot3Over2 = 0.8660254037844386f;
276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_30_60(canvas, SkRRect::kLowerLeft_Corner,
278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   SkVector::Make(0.5f, kRoot3Over2), 120, center);
279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_30_60(canvas, SkRRect::kUpperRight_Corner,
280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   SkVector::Make(kRoot3Over2, 0.5f), 120, center);
281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_30_60(canvas, SkRRect::kUpperLeft_Corner,
283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   SkVector::Make(-0.5f, kRoot3Over2), 120, center);
284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_30_60(canvas, SkRRect::kLowerRight_Corner,
285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   SkVector::Make(-kRoot3Over2, 0.5f), 120, center);
286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_30_60(canvas, SkRRect::kLowerLeft_Corner,
288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   SkVector::Make(-0.5f, -kRoot3Over2), 120, center);
289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_30_60(canvas, SkRRect::kUpperRight_Corner,
290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   SkVector::Make(-kRoot3Over2, -0.5f), 120, center);
291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_30_60(canvas, SkRRect::kUpperLeft_Corner,
293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   SkVector::Make(0.5f, -kRoot3Over2), 120, center);
294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_30_60(canvas, SkRRect::kLowerRight_Corner,
295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   SkVector::Make(kRoot3Over2, -0.5f), 120, center);
296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_45_simple(canvas, SkVector::Make(-SK_ScalarRoot2Over2, -SK_ScalarRoot2Over2),
298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                       210, center);
299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_45_simple(canvas, SkVector::Make(SK_ScalarRoot2Over2, -SK_ScalarRoot2Over2),
300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                       210, center);
301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_45_simple(canvas, SkVector::Make(SK_ScalarRoot2Over2, SK_ScalarRoot2Over2),
302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                       210, center);
303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_45_simple(canvas, SkVector::Make(-SK_ScalarRoot2Over2, SK_ScalarRoot2Over2),
304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                       210, center);
305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_90_simple(canvas, SkVector::Make(-1.0f, 0.0f), 160, center);
307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_90_simple(canvas, SkVector::Make(0.0f, -1.0f), 160, center);
308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_90_simple(canvas, SkVector::Make(1.0f, 0.0f), 160, center);
309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        draw_90_simple(canvas, SkVector::Make(0.0f, 1.0f), 160, center);
310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr int kWidth = 440;
314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr int kHeight = 440;
315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef GM INHERITED;
317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//////////////////////////////////////////////////////////////////////////////
320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM(return new OccludedRRectBlurGM;)
322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
323