• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013 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/gm.h"
9 #include "include/core/SkBitmap.h"
10 #include "include/core/SkBlendMode.h"
11 #include "include/core/SkCanvas.h"
12 #include "include/core/SkColor.h"
13 #include "include/core/SkColorFilter.h"
14 #include "include/core/SkFont.h"
15 #include "include/core/SkImageFilter.h"
16 #include "include/core/SkPaint.h"
17 #include "include/core/SkRRect.h"
18 #include "include/core/SkRect.h"
19 #include "include/core/SkRefCnt.h"
20 #include "include/core/SkScalar.h"
21 #include "include/core/SkTypeface.h"
22 #include "include/core/SkTypes.h"
23 #include "include/effects/SkImageFilters.h"
24 #include "include/utils/SkTextUtils.h"
25 #include "tools/ToolUtils.h"
26 #include "tools/fonts/FontToolUtils.h"
27 
28 #include <utility>
29 
30 ///////////////////////////////////////////////////////////////////////////////
31 
draw_paint(SkCanvas * canvas,const SkRect & r,sk_sp<SkImageFilter> imf)32 static void draw_paint(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) {
33     SkPaint paint;
34     paint.setImageFilter(std::move(imf));
35     paint.setColor(SK_ColorBLACK);
36     canvas->save();
37     canvas->clipRect(r);
38     canvas->drawPaint(paint);
39     canvas->restore();
40 }
41 
draw_path(SkCanvas * canvas,const SkRect & r,sk_sp<SkImageFilter> imf)42 static void draw_path(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) {
43     SkPaint paint;
44     paint.setColor(SK_ColorGREEN);
45     paint.setImageFilter(std::move(imf));
46     paint.setAntiAlias(true);
47     canvas->save();
48     canvas->clipRect(r);
49     canvas->drawCircle(r.centerX(), r.centerY(), r.width()/3, paint);
50     canvas->restore();
51 }
52 
draw_text(SkCanvas * canvas,const SkRect & r,sk_sp<SkImageFilter> imf)53 static void draw_text(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) {
54     SkPaint paint;
55     paint.setImageFilter(std::move(imf));
56     paint.setColor(SK_ColorGREEN);
57     paint.setAntiAlias(true);
58 
59     SkFont font(ToolUtils::DefaultPortableTypeface(), r.height() / 2);
60     canvas->save();
61     canvas->clipRect(r);
62     SkTextUtils::DrawString(canvas, "Text", r.centerX(), r.centerY(), font, paint, SkTextUtils::kCenter_Align);
63     canvas->restore();
64 }
65 
draw_bitmap(SkCanvas * canvas,const SkRect & r,sk_sp<SkImageFilter> imf)66 static void draw_bitmap(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) {
67     SkPaint paint;
68 
69     SkIRect bounds;
70     r.roundOut(&bounds);
71 
72     auto surf = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(bounds.width(), bounds.height()));
73     draw_path(surf->getCanvas(), r, nullptr);
74 
75     paint.setImageFilter(std::move(imf));
76     canvas->save();
77     canvas->clipRect(r);
78     surf->draw(canvas, 0, 0, SkSamplingOptions(), &paint);
79     canvas->restore();
80 }
81 
82 ///////////////////////////////////////////////////////////////////////////////
83 
84 DEF_SIMPLE_GM(dropshadowimagefilter, canvas, 400, 656) {
85     void (*drawProc[])(SkCanvas*, const SkRect&, sk_sp<SkImageFilter>) = {
86         draw_bitmap, draw_path, draw_paint, draw_text
87     };
88 
89     sk_sp<SkColorFilter> cf(SkColorFilters::Blend(SK_ColorMAGENTA, SkBlendMode::kSrcIn));
90     sk_sp<SkImageFilter> cfif(SkImageFilters::ColorFilter(std::move(cf), nullptr));
91     SkIRect cropRect = SkIRect::MakeXYWH(10, 10, 44, 44);
92     SkIRect bogusRect = SkIRect::MakeXYWH(-100, -100, 10, 10);
93 
94     sk_sp<SkColorSpace> spinCS = SkColorSpace::MakeSRGB()->makeColorSpin();
95     sk_sp<SkImageFilter> filters[] = {
96             nullptr,
97             SkImageFilters::DropShadow(7.0f, 0.0f, 0.0f, 3.0f, SK_ColorBLUE, nullptr),
98             SkImageFilters::DropShadow(0.0f, 7.0f, 3.0f, 0.0f, SK_ColorBLUE, nullptr),
99             SkImageFilters::DropShadow(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE, nullptr),
100             SkImageFilters::DropShadow(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE, std::move(cfif)),
101             SkImageFilters::DropShadow(
102                     7.0f, 7.0f, 3.0f, 3.0f, SkColors::kGreen, spinCS, nullptr, &cropRect),
103             SkImageFilters::DropShadow(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE, nullptr, &bogusRect),
104             SkImageFilters::DropShadowOnly(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE, nullptr),
105     };
106 
107     SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
108     SkScalar MARGIN = SkIntToScalar(16);
109     SkScalar DX = r.width() + MARGIN;
110     SkScalar DY = r.height() + MARGIN;
111 
112     canvas->translate(MARGIN, MARGIN);
113     for (size_t j = 0; j < std::size(drawProc); ++j) {
114         canvas->save();
115         for (size_t i = 0; i < std::size(filters); ++i) {
116             drawProc[j](canvas, r, filters[i]);
117             canvas->translate(0, DY);
118         }
119         canvas->restore();
120         canvas->translate(DX, 0);
121     }
122 }
123 
124 DEF_SIMPLE_GM(dropshadow_pseudopersp, canvas, 155, 155) {
125     canvas->clear(SK_ColorLTGRAY);
126     canvas->concat(SkM44{0.5f, 0.f,  0.f, -75.f,
127                          0.f,  0.5f, 0.f, -30.f,
128                          0.f,  0.f,  1.f,  0.f,
129                          0.f,  0.f,  0.f,  1.f});
130     // This 4x4 matrtix technically has perspective, but it only impacts the Z values and the
131     // projection doesn't appear to have any distortion. However, the projected coordinates have
132     // Z values very different from 0. When inversing the device bounds with an assumed Z=0, the
133     // layer bounds end up empty. This GM ensures layer mapping calculations don't discard it.
134     canvas->concat(SkM44{1360.f, 0.f,     275.4f,  294100.f,
135                          0.f,    1360.f,  489.6f,  98344.f,
136                          0.f,    0.f,    -0.51f,  -2180.67f,
137                          0.f,    0.f,     0.51f,   2181.67f});
138 
139     SkRect layerBounds{42.5f, 42.5f, 457.5f, 457.5f};
140     SkPaint layerPaint;
141     layerPaint.setImageFilter(SkImageFilters::DropShadow(
142             /*dx=*/30.f, /*dy=*/30.f,
143             /*sigmaX=*/12.f, /*sigmaY=*/12.f,
144             /*color=*/{0.14902f, 0.215686f, 0.329412f, 0.666667f},
145             /*colorSpace=*/nullptr,
146             /*input=*/nullptr));
147     canvas->saveLayer(&layerBounds, &layerPaint);
148 
149     SkRRect rrect = SkRRect::MakeRectXY({-250.f, -250.f, 250.f, 250.f}, 45.f, 45.f);
150     SkPaint rrectPaint;
151     rrectPaint.setColor4f(SkColors::kWhite);
152     rrectPaint.setAntiAlias(true);
153 
154     canvas->concat(SkM44{0.83f, 0.f,   0.f, 250.f,
155                          0.f,   0.83f, 0.f, 250.f,
156                          0.f,   0.f,   1.f, 0.f,
157                          0.f,   0.f,   0.f, 1.f});
158     canvas->drawRRect(rrect, rrectPaint);
159     canvas->restore();
160 
161     canvas->concat(SkM44{0.83f, 0.f,   0.f, 250.f,
162                          0.f,   0.83f, 0.f, 250.f,
163                          0.f,   0.f,   1.f, 0.f,
164                          0.f,   0.f,   0.f, 1.f});
165 
166     rrectPaint.setColor4f(SkColors::kBlack);
167     rrectPaint.setStyle(SkPaint::kStroke_Style);
168     canvas->drawRRect(rrect, rrectPaint);
169 }
170