Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
conicpaths.cpp
Go to the documentation of this file.
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"
14#include "include/core/SkRect.h"
16#include "include/core/SkSize.h"
21
22using namespace skia_private;
23
24class ConicPathsGM : public skiagm::GM {
25protected:
26 SkString getName() const override { return SkString("conicpaths"); }
27
28 SkISize getISize() override { return SkISize::Make(920, 960); }
29
30 template <typename Proc> void append_path(Proc proc) {
32 proc(&b);
33 fPaths.push_back(b.detach());
34 }
35
36 void onOnceBeforeDraw() override {
37 this->append_path([](SkPathBuilder* conicCircle) {
38 const SkScalar w = SkScalarSqrt(2)/2;
39 conicCircle->moveTo(0, 0);
40 conicCircle->conicTo(0, 50, 50, 50, w);
41 conicCircle->rConicTo(50, 0, 50, -50, w);
42 conicCircle->rConicTo(0, -50, -50, -50, w);
43 conicCircle->rConicTo(-50, 0, -50, 50, w);
44 });
45
46 this->append_path([](SkPathBuilder* hyperbola) {
47 hyperbola->moveTo(0, 0);
48 hyperbola->conicTo(0, 100, 100, 100, 2);
49 });
50
51 this->append_path([](SkPathBuilder* thinHyperbola) {
52 thinHyperbola->moveTo(0, 0);
53 thinHyperbola->conicTo(100, 100, 5, 0, 2);
54 });
55
56 this->append_path([](SkPathBuilder* veryThinHyperbola) {
57 veryThinHyperbola->moveTo(0, 0);
58 veryThinHyperbola->conicTo(100, 100, 1, 0, 2);
59 });
60
61 this->append_path([](SkPathBuilder* closedHyperbola) {
62 closedHyperbola->moveTo(0, 0);
63 closedHyperbola->conicTo(100, 100, 0, 0, 2);
64 });
65
66 this->append_path([](SkPathBuilder* nearParabola) {
67 // using 1 as weight defaults to using quadTo
68 nearParabola->moveTo(0, 0);
69 nearParabola->conicTo(0, 100, 100, 100, 0.999f);
70 });
71
72 this->append_path([](SkPathBuilder* thinEllipse) {
73 thinEllipse->moveTo(0, 0);
74 thinEllipse->conicTo(100, 100, 5, 0, SK_ScalarHalf);
75 });
76
77 this->append_path([](SkPathBuilder* veryThinEllipse) {
78 veryThinEllipse->moveTo(0, 0);
79 veryThinEllipse->conicTo(100, 100, 1, 0, SK_ScalarHalf);
80 });
81
82 this->append_path([](SkPathBuilder* closedEllipse) {
83 closedEllipse->moveTo(0, 0);
84 closedEllipse->conicTo(100, 100, 0, 0, SK_ScalarHalf);
85 });
86
87 {
89 const SkScalar w = SkScalarSqrt(2)/2;
90 b.moveTo(2.1e+11f, -1.05e+11f);
91 b.conicTo(2.1e+11f, 0, 1.05e+11f, 0, w);
92 b.conicTo(0, 0, 0, -1.05e+11f, w);
93 b.conicTo(0, -2.1e+11f, 1.05e+11f, -2.1e+11f, w);
94 b.conicTo(2.1e+11f, -2.1e+11f, 2.1e+11f, -1.05e+11f, w);
95 fGiantCircle = b.detach();
96 }
97 }
98
99 void drawGiantCircle(SkCanvas* canvas) {
101 canvas->drawPath(fGiantCircle, paint);
102 }
103
104 void onDraw(SkCanvas* canvas) override {
105 const SkAlpha kAlphaValue[] = { 0xFF, 0x40 };
106
107 const SkScalar margin = 15;
108 canvas->translate(margin, margin);
109
111 for (int p = 0; p < fPaths.size(); ++p) {
112 canvas->save();
113 for (size_t a = 0; a < std::size(kAlphaValue); ++a) {
114 paint.setARGB(kAlphaValue[a], 0, 0, 0);
115 for (int aa = 0; aa < 2; ++aa) {
116 paint.setAntiAlias(SkToBool(aa));
117 for (int fh = 0; fh < 2; ++fh) {
118 paint.setStroke(fh != 0);
119
120 const SkRect& bounds = fPaths[p].getBounds();
121 canvas->save();
122 canvas->translate(-bounds.fLeft, -bounds.fTop);
123 canvas->drawPath(fPaths[p], paint);
124 canvas->restore();
125
126 canvas->translate(110, 0);
127 }
128 }
129 }
130 canvas->restore();
131 canvas->translate(0, 110);
132 }
133 canvas->restore();
134
135 this->drawGiantCircle(canvas);
136 }
137
138private:
139 TArray<SkPath> fPaths;
140 SkPath fGiantCircle;
141 using INHERITED = skiagm::GM;
142};
143DEF_GM(return new ConicPathsGM;)
144
145//////////////////////////////////////////////////////////////////////////////
146
147/* arc should be on top of circle */
148DEF_SIMPLE_GM(arccirclegap, canvas, 250, 250) {
149 canvas->translate(50, 100);
150 SkPoint c = { 1052.5390625f, 506.8760978034711f };
151 SkScalar radius = 1096.702150363923f;
153 paint.setAntiAlias(true);
154 paint.setStroke(true);
155 canvas->drawCircle(c, radius, paint);
156 SkPath path = SkPathBuilder().moveTo(288.88884710654133f, -280.26680862609f)
157 .arcTo({0, 0}, {-39.00216443306411f, 400.6058925796476f}, radius)
158 .detach();
159 paint.setColor(0xff007f00);
160 canvas->drawPath(path, paint);
161}
162
163/* circle should be antialiased */
164DEF_SIMPLE_GM(largecircle, canvas, 250, 250) {
165 canvas->translate(50, 100);
166 SkPoint c = { 1052.5390625f, 506.8760978034711f };
167 SkScalar radius = 1096.702150363923f;
169 paint.setAntiAlias(true);
170 paint.setStroke(true);
171 canvas->drawCircle(c, radius, paint);
172}
173
174/* ovals should not be blurry */
175DEF_SIMPLE_GM(largeovals, canvas, 250, 250) {
176 // Test EllipseOp
177 SkRect r = SkRect::MakeXYWH(-520, -520, 5000, 4000);
179 paint.setAntiAlias(true);
180 paint.setStroke(true);
181 paint.setStrokeWidth(100);
182 canvas->drawOval(r, paint);
183 r.offset(-15, -15);
184 paint.setColor(SK_ColorDKGRAY);
185 // we use stroke and fill to avoid falling into the SimpleFill path
187 paint.setStrokeWidth(1);
188 canvas->drawOval(r, paint);
189
190 // Test DIEllipseOp
191 canvas->rotate(1.0f);
192 r.offset(55, 55);
193 paint.setColor(SK_ColorGRAY);
194 paint.setStroke(true);
195 paint.setStrokeWidth(100);
196 canvas->drawOval(r, paint);
197 r.offset(-15, -15);
198 paint.setColor(SK_ColorLTGRAY);
200 paint.setStrokeWidth(1);
201 canvas->drawOval(r, paint);
202}
203
204DEF_SIMPLE_GM(crbug_640176, canvas, 250, 250) {
205 SkPathBuilder path;
206 path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
207 path.lineTo(SkBits2Float(0x42cfd89a), SkBits2Float(0xc2700000)); // 103.923f, -60
208 path.lineTo(SkBits2Float(0x42cfd899), SkBits2Float(0xc2700006)); // 103.923f, -60
209 path.conicTo(SkBits2Float(0x42f00000), SkBits2Float(0xc2009d9c),
210 SkBits2Float(0x42f00001), SkBits2Float(0x00000000),
211 SkBits2Float(0x3f7746ea)); // 120, -32.1539f, 120, 0, 0.965926f
212
214 paint.setAntiAlias(true);
215 canvas->translate(125, 125);
216 canvas->drawPath(path.detach(), paint);
217}
constexpr SkColor SK_ColorLTGRAY
Definition SkColor.h:118
uint8_t SkAlpha
Definition SkColor.h:26
constexpr SkColor SK_ColorGRAY
Definition SkColor.h:113
constexpr SkColor SK_ColorDKGRAY
Definition SkColor.h:108
static float SkBits2Float(uint32_t bits)
Definition SkFloatBits.h:48
#define SK_ScalarHalf
Definition SkScalar.h:19
#define SkScalarSqrt(x)
Definition SkScalar.h:42
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
void(* Proc)(SkCanvas *, const SkRect &, const SkPaint &)
Definition blurrect.cpp:42
void drawGiantCircle(SkCanvas *canvas)
SkISize getISize() override
void append_path(Proc proc)
void onDraw(SkCanvas *canvas) override
void onOnceBeforeDraw() override
SkString getName() const override
void restore()
Definition SkCanvas.cpp:465
void translate(SkScalar dx, SkScalar dy)
int save()
Definition SkCanvas.cpp:451
void drawPath(const SkPath &path, const SkPaint &paint)
@ kStrokeAndFill_Style
sets to stroke and fill geometry
Definition SkPaint.h:195
SkPathBuilder & conicTo(SkPoint pt1, SkPoint pt2, SkScalar w)
SkPathBuilder & arcTo(const SkRect &oval, SkScalar startAngleDeg, SkScalar sweepAngleDeg, bool forceMoveTo)
SkPathBuilder & moveTo(SkPoint pt)
SkPathBuilder & rConicTo(SkPoint p1, SkPoint p2, SkScalar w)
SkPath detach()
Definition SkPath.h:147
int size() const
Definition SkTArray.h:416
const Paint & paint
float SkScalar
Definition extension.cpp:12
static bool b
struct MyStruct a[10]
#define DEF_GM(CODE)
Definition gm.h:40
#define DEF_SIMPLE_GM(NAME, CANVAS, W, H)
Definition gm.h:50
SkScalar w
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659
void offset(float dx, float dy)
Definition SkRect.h:1016