Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
convexpolyclip.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 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"
13#include "include/core/SkFont.h"
19#include "include/core/SkRect.h"
22#include "include/core/SkSize.h"
28#include "tools/ToolUtils.h"
30
31static sk_sp<SkImage> make_img(int w, int h) {
33 auto canvas = surf->getCanvas();
34
35 SkScalar wScalar = SkIntToScalar(w);
36 SkScalar hScalar = SkIntToScalar(h);
37
38 SkPoint pt = { wScalar / 2, hScalar / 2 };
39
40 SkScalar radius = 3 * std::max(wScalar, hScalar);
41
42 SkColor colors[] = {SK_ColorDKGRAY,
43 ToolUtils::color_to_565(0xFF222255),
44 ToolUtils::color_to_565(0xFF331133),
45 ToolUtils::color_to_565(0xFF884422),
46 ToolUtils::color_to_565(0xFF000022),
48 ToolUtils::color_to_565(0xFFAABBCC)};
49
50 SkScalar pos[] = {0,
51 SK_Scalar1 / 6,
52 2 * SK_Scalar1 / 6,
53 3 * SK_Scalar1 / 6,
54 4 * SK_Scalar1 / 6,
55 5 * SK_Scalar1 / 6,
57
59 SkRect rect = SkRect::MakeWH(wScalar, hScalar);
60 SkMatrix mat = SkMatrix::I();
61 for (int i = 0; i < 4; ++i) {
63 pt, radius,
64 colors, pos,
65 std::size(colors),
67 0, &mat));
68 canvas->drawRect(rect, paint);
69 rect.inset(wScalar / 8, hScalar / 8);
70 mat.preTranslate(6 * wScalar, 6 * hScalar);
71 mat.postScale(SK_Scalar1 / 3, SK_Scalar1 / 3);
72 }
73
74 SkFont font(ToolUtils::DefaultPortableTypeface(), wScalar / 2.2f);
75
76 paint.setShader(nullptr);
77 paint.setColor(SK_ColorLTGRAY);
78 constexpr char kTxt[] = "Skia";
79 SkPoint texPos = { wScalar / 17, hScalar / 2 + font.getSize() / 2.5f };
80 canvas->drawSimpleText(kTxt, std::size(kTxt)-1, SkTextEncoding::kUTF8,
81 texPos.fX, texPos.fY, font, paint);
82 paint.setColor(SK_ColorBLACK);
84 paint.setStrokeWidth(SK_Scalar1);
85 canvas->drawSimpleText(kTxt, std::size(kTxt)-1, SkTextEncoding::kUTF8,
86 texPos.fX, texPos.fY, font, paint);
87 return surf->makeImageSnapshot();
88}
89
90namespace skiagm {
91/**
92 * This GM tests convex polygon clips.
93 */
94class ConvexPolyClip : public GM {
95public:
97 this->setBGColor(0xFFFFFFFF);
98 }
99
100protected:
101 SkString getName() const override { return SkString("convex_poly_clip"); }
102
103 SkISize getISize() override {
104 // When benchmarking the saveLayer set of draws is skipped.
105 int w = 435;
106 if (kBench_Mode != this->getMode()) {
107 w *= 2;
108 }
109 return SkISize::Make(w, 540);
110 }
111
112 void onOnceBeforeDraw() override {
113 // On < c++17, emplace_back() returns a void :(
114 auto emplace_back = [](std::vector<Clip>& clips) -> Clip& {
115 clips.emplace_back();
116 return clips.back();
117 };
118
119 emplace_back(fClips).setPath(SkPath::Polygon({
120 { 5.f, 5.f},
121 {100.f, 20.f},
122 { 15.f, 100.f},
123 }, false));
124
125 SkPathBuilder hexagon;
126 constexpr SkScalar kRadius = 45.f;
127 const SkPoint center = { kRadius, kRadius };
128 for (int i = 0; i < 6; ++i) {
129 SkScalar angle = 2 * SK_ScalarPI * i / 6;
130 SkPoint point = { SkScalarCos(angle), SkScalarSin(angle) };
131 point.scale(kRadius);
132 point = center + point;
133 if (0 == i) {
134 hexagon.moveTo(point);
135 } else {
136 hexagon.lineTo(point);
137 }
138 }
139 emplace_back(fClips).setPath(hexagon.snapshot());
140
141 SkMatrix scaleM;
142 scaleM.setScale(1.1f, 0.4f, kRadius, kRadius);
143 emplace_back(fClips).setPath(hexagon.detach().makeTransform(scaleM));
144
145 emplace_back(fClips).setRect(SkRect::MakeXYWH(8.3f, 11.6f, 78.2f, 72.6f));
146
147 SkRect rect = SkRect::MakeLTRB(10.f, 12.f, 80.f, 86.f);
148 SkMatrix rotM;
149 rotM.setRotate(23.f, rect.centerX(), rect.centerY());
150 emplace_back(fClips).setPath(SkPath::Rect(rect).makeTransform(rotM));
151
152 fImg = make_img(100, 100);
153 }
154
155 void onDraw(SkCanvas* canvas) override {
156 SkScalar y = 0;
157 constexpr SkScalar kMargin = 10.f;
158
159 SkPaint bgPaint;
160 bgPaint.setAlpha(0x15);
161 SkISize size = canvas->getBaseLayerSize();
162 canvas->drawImageRect(fImg, SkRect::MakeIWH(size.fWidth, size.fHeight),
163 SkSamplingOptions(), &bgPaint);
164
165 constexpr char kTxt[] = "Clip Me!";
167 SkScalar textW = font.measureText(kTxt, std::size(kTxt)-1, SkTextEncoding::kUTF8);
168 SkPaint txtPaint;
169 txtPaint.setColor(SK_ColorDKGRAY);
170
171 SkScalar startX = 0;
172 int testLayers = kBench_Mode != this->getMode();
173 for (int doLayer = 0; doLayer <= testLayers; ++doLayer) {
174 for (const Clip& clip : fClips) {
175 SkScalar x = startX;
176 for (int aa = 0; aa < 2; ++aa) {
177 if (doLayer) {
178 SkRect bounds;
179 clip.getBounds(&bounds);
180 bounds.outset(2, 2);
181 bounds.offset(x, y);
182 canvas->saveLayer(&bounds, nullptr);
183 } else {
184 canvas->save();
185 }
186 canvas->translate(x, y);
187 clip.setOnCanvas(canvas, SkClipOp::kIntersect, SkToBool(aa));
188 canvas->drawImage(fImg, 0, 0);
189 canvas->restore();
190 x += fImg->width() + kMargin;
191 }
192 for (int aa = 0; aa < 2; ++aa) {
193
194 SkPaint clipOutlinePaint;
195 clipOutlinePaint.setAntiAlias(true);
196 clipOutlinePaint.setColor(0x50505050);
197 clipOutlinePaint.setStyle(SkPaint::kStroke_Style);
198 clipOutlinePaint.setStrokeWidth(0);
199
200 if (doLayer) {
201 SkRect bounds;
202 clip.getBounds(&bounds);
203 bounds.outset(2, 2);
204 bounds.offset(x, y);
205 canvas->saveLayer(&bounds, nullptr);
206 } else {
207 canvas->save();
208 }
209 canvas->translate(x, y);
210 SkPath closedClipPath = clip.asClosedPath();
211 canvas->drawPath(closedClipPath, clipOutlinePaint);
212 clip.setOnCanvas(canvas, SkClipOp::kIntersect, SkToBool(aa));
213 canvas->scale(1.f, 1.8f);
214 canvas->drawSimpleText(kTxt, std::size(kTxt)-1, SkTextEncoding::kUTF8,
215 0, 1.5f * font.getSize(), font, txtPaint);
216 canvas->restore();
217 x += textW + 2 * kMargin;
218 }
219 y += fImg->height() + kMargin;
220 }
221 y = 0;
222 startX += 2 * fImg->width() + SkScalarCeilToInt(2 * textW) + 6 * kMargin;
223 }
224 }
225
226 bool runAsBench() const override { return true; }
227
228private:
229 class Clip {
230 public:
231 enum ClipType {
232 kNone_ClipType,
233 kPath_ClipType,
234 kRect_ClipType
235 };
236
237 Clip () : fClipType(kNone_ClipType) {}
238
239 void setOnCanvas(SkCanvas* canvas, SkClipOp op, bool aa) const {
240 switch (fClipType) {
241 case kPath_ClipType:
242 canvas->clipPath(fPathBuilder.snapshot(), op, aa);
243 break;
244 case kRect_ClipType:
245 canvas->clipRect(fRect, op, aa);
246 break;
247 case kNone_ClipType:
248 SkDEBUGFAIL("Uninitialized Clip.");
249 break;
250 }
251 }
252
253 SkPath asClosedPath() const {
254 switch (fClipType) {
255 case kPath_ClipType:
256 return SkPathBuilder(fPathBuilder).close().detach();
257 case kRect_ClipType:
258 return SkPath::Rect(fRect);
259 case kNone_ClipType:
260 SkDEBUGFAIL("Uninitialized Clip.");
261 break;
262 }
263 return SkPath();
264 }
265
266 void setPath(const SkPath& path) {
267 fClipType = kPath_ClipType;
268 fPathBuilder = path;
269 }
270
271 void setRect(const SkRect& rect) {
272 fClipType = kRect_ClipType;
273 fRect = rect;
274 fPathBuilder.reset();
275 }
276
277 ClipType getType() const { return fClipType; }
278
279 void getBounds(SkRect* bounds) const {
280 switch (fClipType) {
281 case kPath_ClipType:
282 *bounds = fPathBuilder.computeBounds();
283 break;
284 case kRect_ClipType:
285 *bounds = fRect;
286 break;
287 case kNone_ClipType:
288 SkDEBUGFAIL("Uninitialized Clip.");
289 break;
290 }
291 }
292
293 private:
294 ClipType fClipType;
295 SkPathBuilder fPathBuilder;
297 };
298
299 std::vector<Clip> fClips;
300 sk_sp<SkImage> fImg;
301
302 using INHERITED = GM;
303};
304
305DEF_GM(return new ConvexPolyClip;)
306} // namespace skiagm
SkRect fRect
SkPoint pos
@ kOpaque_SkAlphaType
pixel is opaque
Definition SkAlphaType.h:28
#define SkDEBUGFAIL(message)
Definition SkAssert.h:118
SkClipOp
Definition SkClipOp.h:13
constexpr SkColor SK_ColorLTGRAY
Definition SkColor.h:118
uint32_t SkColor
Definition SkColor.h:37
constexpr SkColor SK_ColorBLACK
Definition SkColor.h:103
constexpr SkColor SK_ColorWHITE
Definition SkColor.h:122
constexpr SkColor SK_ColorDKGRAY
Definition SkColor.h:108
@ kUTF8
uses bytes to represent UTF-8 or ASCII
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition SkPath.cpp:3824
#define SkScalarSin(radians)
Definition SkScalar.h:45
#define SK_Scalar1
Definition SkScalar.h:18
#define SkScalarCeilToInt(x)
Definition SkScalar.h:36
#define SkIntToScalar(x)
Definition SkScalar.h:57
#define SkScalarCos(radians)
Definition SkScalar.h:46
#define SK_ScalarPI
Definition SkScalar.h:21
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
static SkScalar center(float pos0, float pos1)
@ kMargin
int saveLayer(const SkRect *bounds, const SkPaint *paint)
Definition SkCanvas.cpp:500
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
void restore()
Definition SkCanvas.cpp:465
void drawSimpleText(const void *text, size_t byteLength, SkTextEncoding encoding, SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
void translate(SkScalar dx, SkScalar dy)
virtual SkISize getBaseLayerSize() const
Definition SkCanvas.cpp:373
void clipPath(const SkPath &path, SkClipOp op, bool doAntiAlias)
void drawImageRect(const SkImage *, const SkRect &src, const SkRect &dst, const SkSamplingOptions &, const SkPaint *, SrcRectConstraint)
int save()
Definition SkCanvas.cpp:451
void drawPath(const SkPath &path, const SkPaint &paint)
void scale(SkScalar sx, SkScalar sy)
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition SkCanvas.h:1528
static sk_sp< SkShader > MakeRadial(const SkPoint &center, SkScalar radius, const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
int width() const
Definition SkImage.h:285
int height() const
Definition SkImage.h:291
SkMatrix & postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Definition SkMatrix.cpp:360
SkMatrix & setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Definition SkMatrix.cpp:296
SkMatrix & setRotate(SkScalar degrees, SkScalar px, SkScalar py)
Definition SkMatrix.cpp:452
static const SkMatrix & I()
SkMatrix & preTranslate(SkScalar dx, SkScalar dy)
Definition SkMatrix.cpp:263
void setStyle(Style style)
Definition SkPaint.cpp:105
void setColor(SkColor color)
Definition SkPaint.cpp:119
void setAntiAlias(bool aa)
Definition SkPaint.h:170
@ kStroke_Style
set to stroke geometry
Definition SkPaint.h:194
void setAlpha(U8CPU a)
Definition SkPaint.h:279
void setStrokeWidth(SkScalar width)
Definition SkPaint.cpp:159
SkPathBuilder & close()
SkPathBuilder & lineTo(SkPoint pt)
SkPathBuilder & moveTo(SkPoint pt)
SkPath snapshot() const
static SkPath Rect(const SkRect &, SkPathDirection=SkPathDirection::kCW, unsigned startIndex=0)
Definition SkPath.cpp:3518
const SkRect & getBounds() const
Definition SkPath.cpp:420
static SkPath Polygon(const SkPoint pts[], int count, bool isClosed, SkPathFillType=SkPathFillType::kWinding, bool isVolatile=false)
Definition SkPath.cpp:3546
SkPath makeTransform(const SkMatrix &m, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
Definition SkPath.h:1392
void reset(T *ptr=nullptr)
Definition SkRefCnt.h:310
SkISize getISize() override
void onDraw(SkCanvas *canvas) override
SkString getName() const override
void onOnceBeforeDraw() override
bool runAsBench() const override
GM(SkColor backgroundColor=SK_ColorWHITE)
Definition gm.cpp:81
@ kBench_Mode
Definition gm.h:121
Mode getMode() const
Definition gm.h:125
void setBGColor(SkColor)
Definition gm.cpp:159
const Paint & paint
float SkScalar
Definition extension.cpp:12
#define DEF_GM(CODE)
Definition gm.h:40
static sk_sp< SkImage > make_img()
double y
double x
Optional< SkRect > bounds
Definition SkRecords.h:189
sk_sp< SkBlender > blender SkRect rect
Definition SkRecords.h:350
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
sk_sp< SkTypeface > DefaultPortableTypeface()
SkColor color_to_565(SkColor color)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
SkScalar w
SkScalar h
constexpr int kRadius
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
static SkImageInfo MakeN32(int width, int height, SkAlphaType at)
float fX
x-axis value
void scale(float scale, SkPoint *dst) const
Definition SkPoint.cpp:17
float fY
y-axis value
static SkRect MakeIWH(int w, int h)
Definition SkRect.h:623
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition SkRect.h:646