Flutter Engine
The Flutter Engine
sharedcorners.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2018 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/SkPath.h"
15#include "include/core/SkRect.h"
17#include "include/core/SkSize.h"
20#include "src/base/SkRandom.h"
21#include "tools/ToolUtils.h"
22
23#include <array>
24#include <vector>
25
26namespace skiagm {
27
28static constexpr int kPadSize = 20;
29static constexpr int kBoxSize = 100;
30static constexpr SkPoint kJitters[] = {{0, 0}, {.5f, .5f}, {2/3.f, 1/3.f}};
31
32// Tests various corners of different angles falling on the same pixel, particularly to ensure
33// analytic AA is working properly.
34class SharedCornersGM : public GM {
35public:
37
38protected:
39 SkString getName() const override { return SkString("sharedcorners"); }
40
41 SkISize getISize() override {
42 constexpr int numRows = 3 * 2;
43 constexpr int numCols = (1 + std::size(kJitters)) * 2;
44 return SkISize::Make(numCols * (kBoxSize + kPadSize) + kPadSize,
45 numRows * (kBoxSize + kPadSize) + kPadSize);
46 }
47
48 void onOnceBeforeDraw() override {
51
54
55 }
56
57 void onDraw(SkCanvas* canvas) override {
58 canvas->translate(kPadSize, kPadSize);
59 canvas->save();
60
61 // Adjacent rects.
62 this->drawTriangleBoxes(canvas,
63 {{0, 0}, {40, 0}, {80, 0}, {120, 0},
64 {0, 20}, {40, 20}, {80, 20}, {120, 20},
65 {40, 40}, {80, 40},
66 {40, 60}, {80, 60}},
67 {{{0, 1, 4}}, {{1, 5, 4}},
68 {{5, 1, 6}}, {{1, 2, 6}},
69 {{2, 3, 6}}, {{3, 7, 6}},
70 {{8, 5, 9}}, {{5, 6, 9}},
71 {{10, 8, 11}}, {{8, 9, 11}}});
72
73 // Obtuse angles.
74 this->drawTriangleBoxes(canvas,
75 {{ 0, 0}, {10, 0}, {20, 0},
76 { 0, 2}, {20, 2},
77 {10, 4},
78 { 0, 6}, {20, 6},
79 { 0, 8}, {10, 8}, {20, 8}},
80 {{{3, 1, 4}}, {{4, 5, 3}}, {{6, 5, 7}}, {{7, 9, 6}},
81 {{0, 1, 3}}, {{1, 2, 4}},
82 {{3, 5, 6}}, {{5, 4, 7}},
83 {{6, 9, 8}}, {{9, 7, 10}}});
84
85 canvas->restore();
86 canvas->translate((kBoxSize + kPadSize) * 4, 0);
87
88 // Right angles.
89 this->drawTriangleBoxes(canvas,
90 {{0, 0}, {-1, 0}, {0, -1}, {1, 0}, {0, 1}},
91 {{{0, 1, 2}}, {{0, 2, 3}}, {{0, 3, 4}}, {{0, 4, 1}}});
92
93 // Acute angles.
94 SkRandom rand;
95 std::vector<SkPoint> pts;
96 std::vector<std::array<int, 3>> indices;
97 SkScalar theta = 0;
98 pts.push_back({0, 0});
99 while (theta < 2*SK_ScalarPI) {
100 pts.push_back({SkScalarCos(theta), SkScalarSin(theta)});
101 if (pts.size() > 2) {
102 indices.push_back({{0, (int)pts.size() - 2, (int)pts.size() - 1}});
103 }
104 theta += rand.nextRangeF(0, SK_ScalarPI/3);
105 }
106 indices.push_back({{0, (int)pts.size() - 1, 1}});
107 this->drawTriangleBoxes(canvas, pts, indices);
108 }
109
110 void drawTriangleBoxes(SkCanvas* canvas, const std::vector<SkPoint>& points,
111 const std::vector<std::array<int, 3>>& triangles) {
112 SkPath path;
113 path.setFillType(SkPathFillType::kEvenOdd);
114 path.setIsVolatile(true);
115 for (const std::array<int, 3>& triangle : triangles) {
116 path.moveTo(points[triangle[0]]);
117 path.lineTo(points[triangle[1]]);
118 path.lineTo(points[triangle[2]]);
119 path.close();
120 }
121 SkScalar scale = kBoxSize / std::max(path.getBounds().height(), path.getBounds().width());
122 path.transform(SkMatrix::Scale(scale, scale));
123
124 this->drawRow(canvas, path);
125 canvas->translate(0, kBoxSize + kPadSize);
126
127 SkMatrix rot;
128 rot.setRotate(45, path.getBounds().centerX(), path.getBounds().centerY());
129 path.transform(rot);
130 this->drawRow(canvas, path);
131 canvas->translate(0, kBoxSize + kPadSize);
132
133 rot.setRotate(-45 - 69.38111f, path.getBounds().centerX(), path.getBounds().centerY());
134 path.transform(rot);
135 this->drawRow(canvas, path);
136 canvas->translate(0, kBoxSize + kPadSize);
137 }
138
139 void drawRow(SkCanvas* canvas, const SkPath& path) {
140 SkAutoCanvasRestore acr(canvas, true);
141 const SkRect& bounds = path.getBounds();
142 canvas->translate((kBoxSize - bounds.width()) / 2 - bounds.left(),
143 (kBoxSize - bounds.height()) / 2 - bounds.top());
144
145 canvas->drawPath(path, fWireFramePaint);
146 canvas->translate(kBoxSize + kPadSize, 0);
147
148 for (SkPoint jitter : kJitters) {
149 {
150 SkAutoCanvasRestore acr2(canvas, true);
151 canvas->translate(jitter.x(), jitter.y());
152 canvas->drawPath(path, fFillPaint);
153 }
154 canvas->translate(kBoxSize + kPadSize, 0);
155 }
156 }
157
160};
161
162DEF_GM(return new SharedCornersGM;)
163
164} // namespace skiagm
static const int points[]
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
#define SkScalarSin(radians)
Definition: SkScalar.h:45
#define SkScalarCos(radians)
Definition: SkScalar.h:46
#define SK_ScalarPI
Definition: SkScalar.h:21
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
int save()
Definition: SkCanvas.cpp:447
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition: SkMatrix.h:75
SkMatrix & setRotate(SkScalar degrees, SkScalar px, SkScalar py)
Definition: SkMatrix.cpp:452
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
Definition: SkPath.h:59
float nextRangeF(float min, float max)
Definition: SkRandom.h:64
Definition: gm.h:110
void setBGColor(SkColor)
Definition: gm.cpp:159
void onDraw(SkCanvas *canvas) override
void drawTriangleBoxes(SkCanvas *canvas, const std::vector< SkPoint > &points, const std::vector< std::array< int, 3 > > &triangles)
SkISize getISize() override
void drawRow(SkCanvas *canvas, const SkPath &path)
void onOnceBeforeDraw() override
SkString getName() const override
float SkScalar
Definition: extension.cpp:12
static float max(float r, float g, float b)
Definition: hsl.cpp:49
Optional< SkRect > bounds
Definition: SkRecords.h:189
SkColor color_to_565(SkColor color)
Definition: ToolUtils.cpp:139
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
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
static constexpr SkPoint kJitters[]
DEF_GM(return F(C(clipbox), 0.0f, 0.0f, {})) DEF_GM(return F(C(clipbox)
static constexpr int kPadSize
static SkPath scale(const SkPath &path, SkScalar scale)
Definition: patheffects.cpp:68
static constexpr int kBoxSize
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20