16#include <unordered_set>
34 float s1 =
a*
a +
b*
b + c*c +
d*
d;
36 float e =
a*
a +
b*
b - c*c -
d*
d;
43 return {singular1, singular2};
76 const float dxdu =
matrix.rc(0,0);
77 const float dxdv =
matrix.rc(0,1);
78 const float dydu =
matrix.rc(1,0);
79 const float dydv =
matrix.rc(1,1);
80 const float dwdu =
matrix.rc(3,0);
81 const float dwdv =
matrix.rc(3,1);
83 float invW2 = 1.f / (devP.
w * devP.
w);
85 float dfdu = (devP.
w*dxdu - devP.
x*dwdu) * invW2;
86 float dfdv = (devP.
w*dxdv - devP.
x*dwdv) * invW2;
87 float dgdu = (devP.
w*dydu - devP.
y*dwdu) * invW2;
88 float dgdv = (devP.
w*dydv - devP.
y*dwdv) * invW2;
118 const SkV2& cornerRadii,
const SkV4& devCenter,
float centerWeight,
119 float strokeRadius,
float joinScale,
float localAARadius)
const {
120 const bool snapToCenter = centerWeight +
fCenterWeight > 0.f;
122 return {devCenter.
x, devCenter.
y, devCenter.
w};
129 normalizedPos =
scale*normalizedPos - cornerRadii;
134 if (maxInset.
x < 0.f || maxInset.
y < 0.f) {
139 normalizedPos += localAARadius *
fNormal;
144 {cornerMapping.
x*normalizedPos.
x + cornerMapping.
y*normalizedPos.
y + cornerPt.
x,
145 cornerMapping.
z*normalizedPos.
x + cornerMapping.
w*normalizedPos.
y + cornerPt.
y};
146 SkV4 devPos =
m.map(localPos.
x, localPos.
y, 0.f, 1.f);
148 const bool deviceSpaceNormal =
150 if (deviceSpaceNormal) {
164 float px = cornerMapping.
y*cornerPt.
y - cornerMapping.
w*cornerPt.
x;
165 float py = cornerMapping.
z*cornerPt.
x - cornerMapping.
x*cornerPt.
y;
189 if (normX.
dot(normY) < -0.8) {
192 float sign = normX.
cross(normY) >= 0.f ? 1.f : -1.f;
209 return SkV3{devPos.
x, devPos.
y, devPos.
w};
225 { {0.0f, 1.0f}, { 0.0f, 1.0f}, 1.0f, 0.0f, -2.f },
226 { {0.0f, 1.0f}, { 0.0f, 1.0f}, 1.0f, 1.0f, -2.f },
227 { {0.0f, 1.0f}, {
kHR2,
kHR2}, 1.0f, 1.0f, -2.f },
228 { {1.0f, 0.0f}, {
kHR2,
kHR2}, 1.0f, 1.0f, -2.f },
229 { {1.0f, 0.0f}, { 1.0f, 0.0f}, 1.0f, 1.0f, -2.f },
230 { {1.0f, 0.0f}, { 1.0f, 0.0f}, 1.0f, 0.0f, -2.f },
233 { {0.0f, 1.0f}, { 0.0f, 0.0f}, 1.0f, 0.0f, -2.f },
234 { {0.0f, 1.0f}, { 0.0f, 0.0f}, 1.0f, 1.0f, -2.f },
235 { {1.0f, 0.0f}, { 0.0f, 0.0f}, 1.0f, 1.0f, -2.f },
236 { {1.0f, 0.0f}, { 0.0f, 0.0f}, 1.0f, 0.0f, -2.f },
239 { {0.0f, 1.0f}, { 0.0f, 0.0f}, 0.0f, 0.0f, -2.f },
240 { {0.0f, 1.0f}, { 0.0f, 0.0f}, 0.0f, 1.0f, -2.f },
241 { {1.0f, 0.0f}, { 0.0f, 0.0f}, 0.0f, 1.0f, -2.f },
242 { {1.0f, 0.0f}, { 0.0f, 0.0f}, 0.0f, 0.0f, -2.f },
245 { {0.0f, 1.0f}, { 0.0f, -1.0f}, -1.0f, 0.0f, -1.f },
246 { {0.5f, 0.5f}, {-
kHR2, -
kHR2}, -1.0f, 1.0f, -1.f },
247 { {1.0f, 0.0f}, {-1.0f, 0.0f}, -1.0f, 0.0f, -1.f },
250 { {0.5f, 0.5f}, {-
kHR2, -
kHR2}, -1.0f, 1.0f, 0.f },
251 { {1.0f, 0.0f}, {-1.0f, 0.0f}, -1.0f, 0.0f, 0.f },
256 float centerWeight,
float localAARadius,
float strokeRadius,
262 if (cornerRadii.
x <= 0.f || cornerRadii.
y <= 0.f) {
265 if (strokeRadius > 0.f) {
281 center, centerWeight, strokeRadius, joinScale,
305 float centerWeight = 0.f;
306 if (strokeRadius < 0.f) {
318 float maxInset = strokeRadius + localAARadius;
336 static constexpr SkV4 kBRBasis = { 1.f, 0.f, 0.f, 1.f};
337 static constexpr SkV4 kTRBasis = { 0.f, 1.f, -1.f, 0.f};
338 static constexpr SkV4 kTLBasis = {-1.f, 0.f, 0.f, -1.f};
339 static constexpr SkV4 kBLBasis = { 0.f, -1.f, 1.f, 0.f};
346 devCenter, centerWeight, localAARadius, strokeRadius,
join);
352 devCenter, centerWeight, localAARadius,strokeRadius,
join);
358 devCenter, centerWeight, localAARadius,strokeRadius,
join);
364 devCenter, centerWeight, localAARadius,strokeRadius,
join);
370 kBR+0,
kBR+6,
kBR+1,
kBR+7,
kBR+2,
kBR+8,
kBR+3,
kBR+8,
kBR+4,
kBR+9,
kBR+5,
kBR+9,
371 kTR+0,
kTR+6,
kTR+1,
kTR+7,
kTR+2,
kTR+8,
kTR+3,
kTR+8,
kTR+4,
kTR+9,
kTR+5,
kTR+9,
372 kTL+0,
kTL+6,
kTL+1,
kTL+7,
kTL+2,
kTL+8,
kTL+3,
kTL+8,
kTL+4,
kTL+9,
kTL+5,
kTL+9,
373 kBL+0,
kBL+6,
kBL+1,
kBL+7,
kBL+2,
kBL+8,
kBL+3,
kBL+8,
kBL+4,
kBL+9,
kBL+5,
kBL+9,
396 kBR+0,
kBR+0,
kBR+6,
kBR+1,
kBR+7,
kBR+2,
kBR+8,
kBR+3,
kBR+8,
kBR+4,
kBR+9,
kBR+5,
kBR+5,
397 kTR+0,
kTR+0,
kTR+6,
kTR+1,
kTR+7,
kTR+2,
kTR+8,
kTR+3,
kTR+8,
kTR+4,
kTR+9,
kTR+5,
kTR+5,
398 kTL+0,
kTL+0,
kTL+6,
kTL+1,
kTL+7,
kTL+2,
kTL+8,
kTL+3,
kTL+8,
kTL+4,
kTL+9,
kTL+5,
kTL+5,
399 kBL+0,
kBL+0,
kBL+6,
kBL+1,
kBL+7,
kBL+2,
kBL+8,
kBL+3,
kBL+8,
kBL+4,
kBL+9,
kBL+5,
kBL+5,
401 kBR+6,
kBR+6,
kBR+10,
kBR+7,
kBR+11,
kBR+8,
kBR+12,
kBR+9,
kBR+13,
kBR+13,
402 kTR+6,
kTR+6,
kTR+10,
kTR+7,
kTR+11,
kTR+8,
kTR+12,
kTR+9,
kTR+13,
kTR+13,
403 kTL+6,
kTL+6,
kTL+10,
kTL+7,
kTL+11,
kTL+8,
kTL+12,
kTL+9,
kTL+13,
kTL+13,
441 static constexpr float kControlPointRadius = 3.f;
442 static constexpr float kBaseScale = 50.f;
446 : fOrigin{300.f, 300.f}
447 , fXAxisPoint{300.f + kBaseScale, 300.f}
448 , fYAxisPoint{300.f, 300.f + kBaseScale}
450 , fJoinMode(
SkPaint::kMiter_Join)
451 , fMode(PrimitiveMode::kFillRect) {
452 fName =
"GraphitePrimitives";
459 canvas->
concat(this->basisMatrix());
471 this->drawVertices(canvas, totalMatrix);
473 SkV4 origin = viewMatrix.
map(fOrigin.
x, fOrigin.
y, 0.f, 1.f);
474 SkV4 xAxis = viewMatrix.
map(fXAxisPoint.
x, fXAxisPoint.
y, 0.f, 1.f);
475 SkV4 yAxis = viewMatrix.
map(fYAxisPoint.
x, fYAxisPoint.
y, 0.f, 1.f);
478 canvas->
drawLine({origin.
x/origin.
w, origin.
y/origin.
w},
480 canvas->
drawLine({origin.
x/origin.
w, origin.
y/origin.
w},
502 enum class PrimitiveMode {
510 SkM44 basisMatrix()
const {
511 SkV2 xAxis = (fXAxisPoint - fOrigin) / kBaseScale;
512 SkV2 yAxis = (fYAxisPoint - fOrigin) / kBaseScale;
515 {yAxis.
x, yAxis.
y, 0.f, 0.f},
516 {0.f, 0.f, 1.f, 0.f},
517 {fOrigin.
x, fOrigin.
y, 0.f, 1.f});
521 if (
fMode == PrimitiveMode::kFillRect ||
fMode == PrimitiveMode::kFillRRect) {
527 SkRRect primitiveShape()
const {
529 kBaseScale, kBaseScale);
531 static const SkVector kOuterRadii[4] = { { 0.25f * kBaseScale, 0.75f * kBaseScale },
533 { 0.5f * kBaseScale, 0.5f * kBaseScale },
534 { 0.75f * kBaseScale, 0.25f * kBaseScale } };
536 static const SkVector kStrokeRadii[4] = { { 0.25f * kBaseScale, 0.25f * kBaseScale },
538 { 0.5f * kBaseScale, 0.5f * kBaseScale },
539 { 0.75f * kBaseScale, 0.75f * kBaseScale } };
541 float strokeRadius = 0.5f * fStrokeWidth;
543 case PrimitiveMode::kFillRect:
545 case PrimitiveMode::kFillRRect: {
550 case PrimitiveMode::kStrokeRect:
552 case PrimitiveMode::kStrokeRRect: {
576 const uint16_t* indices,
580 nullptr,
nullptr, (
int) indexCount, indices);
605 std::unordered_set<uint32_t> edges;
606 auto drawEdge = [&edges, vertices, canvas](uint16_t
e0, uint16_t
e1) {
608 if (edges.find(edgeID) == edges.end()) {
609 edges.insert(edgeID);
635 bool fColorize =
true;
653 auto selected = [
x,
y](
const SkV2&
p) {
657 if (selected(fOrigin)) {
658 return new Click(&fOrigin);
659 }
else if (selected(fXAxisPoint)) {
660 return new Click(&fXAxisPoint);
661 }
else if (selected(fYAxisPoint)) {
662 return new Click(&fYAxisPoint);
677 fMode = PrimitiveMode::kFillRect;
680 fMode = PrimitiveMode::kFillRRect;
683 fMode = PrimitiveMode::kStrokeRect;
686 fMode = PrimitiveMode::kStrokeRRect;
689 fStrokeWidth =
std::max(0.f, fStrokeWidth - 0.4f);
692 fStrokeWidth =
std::min(5 * kBaseScale, fStrokeWidth + 0.4f);
705 fOrigin = {300.f, 300.f};
706 fXAxisPoint = {300.f + kBaseScale, 300.f};
707 fYAxisPoint = {300.f, 300.f + kBaseScale};
710 fColorize = !fColorize;
static SkM44 inv(const SkM44 &m)
static const int strokeWidth
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
static const uint16_t kOuterCornerIndices[]
static const uint16_t kEdgeIndices[]
static constexpr float kMiterScale
static const uint16_t kTL
static void compute_vertices(SkV3 devPts[kVertexCount], const SkM44 &m, const SkRRect &rrect, float strokeRadius, SkPaint::Join join)
static const uint16_t kBL
static constexpr float kAARadius
static const size_t kVertexCount
static const uint16_t kInteriorIndices[]
static const uint16_t kIndices[]
static const uint16_t kBR
static constexpr float kBevelScale
static SkPaint paint(SkColor color, float strokeWidth=-1.f, SkPaint::Join join=SkPaint::kMiter_Join)
static constexpr LocalCornerVert kCornerTemplate[19]
static const uint16_t kTR
static std::pair< float, float > singular_values(float a, float b, float c, float d)
static float local_aa_radius(const SkM44 &matrix, const SkV2 &p)
static void compute_corner(SkV3 devPts[19], const SkM44 &m, const SkV4 &cornerMapping, const SkV2 &cornerPt, const SkV2 &cornerRadii, const SkV4 ¢er, float centerWeight, float localAARadius, float strokeRadius, SkPaint::Join join)
static constexpr float kRoundScale
static constexpr float kHR2
static const uint16_t kInnerCornerIndices[]
static const int points[]
constexpr SkColor SK_ColorMAGENTA
constexpr SkColor SK_ColorCYAN
constexpr SkColor SK_ColorGRAY
constexpr SkColor SK_ColorBLUE
constexpr SkColor SK_ColorRED
constexpr SkColor SK_ColorBLACK
constexpr SkColor SK_ColorGREEN
constexpr SkColor SK_ColorDKGRAY
constexpr float SK_FloatSqrt2
static int sign(SkScalar x)
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
#define SK_ScalarNearlyZero
#define SK_ScalarRoot2Over2
static SkScalar center(float pos0, float pos1)
void draw(SkCanvas *canvas) override
bool onClick(Click *) override
Click * onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override
GraphitePrimitivesSlide()
bool onChar(SkUnichar) override
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
SkM44 getLocalToDevice() const
void drawRRect(const SkRRect &rrect, const SkPaint &paint)
void concat(const SkMatrix &matrix)
void drawVertices(const SkVertices *vertices, SkBlendMode mode, const SkPaint &paint)
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint &paint)
SkV4 map(float x, float y, float z, float w) const
static SkM44 Cols(const SkV4 &c0, const SkV4 &c1, const SkV4 &c2, const SkV4 &c3)
void setStyle(Style style)
void setColor(SkColor color)
void setAntiAlias(bool aa)
@ kStroke_Style
set to stroke geometry
void setStrokeJoin(Join join)
@ kMiter_Join
extends to miter limit
@ kBevel_Join
connects outside edges
void setStrokeWidth(SkScalar width)
void outset(SkScalar dx, SkScalar dy, SkRRect *dst) const
SkVector radii(Corner corner) const
@ kUpperLeft_Corner
index of top-left corner radii
@ kLowerRight_Corner
index of bottom-right corner radii
@ kUpperRight_Corner
index of top-right corner radii
@ kLowerLeft_Corner
index of bottom-left corner radii
static SkRRect MakeRect(const SkRect &r)
void setRectRadii(const SkRect &rect, const SkVector radii[4])
const SkRect & getBounds() const
static sk_sp< SkVertices > MakeCopy(VertexMode mode, int vertexCount, const SkPoint positions[], const SkPoint texs[], const SkColor colors[], int indexCount, const uint16_t indices[])
@ kTriangleStrip_VertexMode
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
static float max(float r, float g, float b)
static float min(float r, float g, float b)
unsigned useCenter Optional< SkMatrix > matrix
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
SIN Vec< N, float > normalize(const Vec< N, float > &v)
static SkString join(const CommandLineFlags::StringArray &)
SkV3 transform(const SkM44 &m, const SkV4 &cornerMapping, const SkV2 &cornerPt, const SkV2 &cornerRadii, const SkV4 &devCenter, float centerWeight, float strokeRadius, float joinScale, float localAARadius) const
SkScalar fBottom
larger y-axis bounds
SkRect makeOutset(float dx, float dy) const
constexpr float centerX() const
constexpr float centerY() const
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
SkScalar fTop
smaller y-axis bounds
SkScalar dot(SkV2 v) const
SkScalar cross(SkV2 v) const
SkScalar dot(const SkV4 &v) const