Flutter Engine
The Flutter Engine
Public Member Functions | Friends | List of all members
SkStroke Class Reference

#include <SkStroke.h>

Public Member Functions

 SkStroke ()
 
 SkStroke (const SkPaint &)
 
 SkStroke (const SkPaint &, SkScalar width)
 
SkPaint::Cap getCap () const
 
void setCap (SkPaint::Cap)
 
SkPaint::Join getJoin () const
 
void setJoin (SkPaint::Join)
 
void setMiterLimit (SkScalar)
 
void setWidth (SkScalar)
 
bool getDoFill () const
 
void setDoFill (bool doFill)
 
SkScalar getResScale () const
 
void setResScale (SkScalar rs)
 
void strokeRect (const SkRect &rect, SkPath *result, SkPathDirection=SkPathDirection::kCW) const
 
void strokePath (const SkPath &path, SkPath *) const
 

Friends

class SkPaint
 

Detailed Description

SkStroke is the utility class that constructs paths by stroking geometries (lines, rects, ovals, roundrects, paths). This is invoked when a geometry or text is drawn in a canvas with the kStroke_Mask bit set in the paint.

Definition at line 36 of file SkStroke.h.

Constructor & Destructor Documentation

◆ SkStroke() [1/3]

SkStroke::SkStroke ( )

Definition at line 1358 of file SkStroke.cpp.

1358 {
1359 fWidth = SK_Scalar1;
1360 fMiterLimit = SkPaintDefaults_MiterLimit;
1361 fResScale = 1;
1362 fCap = SkPaint::kDefault_Cap;
1363 fJoin = SkPaint::kDefault_Join;
1364 fDoFill = false;
1365}
#define SkPaintDefaults_MiterLimit
#define SK_Scalar1
Definition: SkScalar.h:18
@ kDefault_Cap
equivalent to kButt_Cap
Definition: SkPaint.h:338
@ kDefault_Join
equivalent to kMiter_Join
Definition: SkPaint.h:363

◆ SkStroke() [2/3]

SkStroke::SkStroke ( const SkPaint p)

Definition at line 1367 of file SkStroke.cpp.

1367 {
1368 fWidth = p.getStrokeWidth();
1369 fMiterLimit = p.getStrokeMiter();
1370 fResScale = 1;
1371 fCap = (uint8_t)p.getStrokeCap();
1372 fJoin = (uint8_t)p.getStrokeJoin();
1373 fDoFill = SkToU8(p.getStyle() == SkPaint::kStrokeAndFill_Style);
1374}
constexpr uint8_t SkToU8(S x)
Definition: SkTo.h:22
@ kStrokeAndFill_Style
sets to stroke and fill geometry
Definition: SkPaint.h:195

◆ SkStroke() [3/3]

SkStroke::SkStroke ( const SkPaint p,
SkScalar  width 
)

Definition at line 1376 of file SkStroke.cpp.

1376 {
1377 fWidth = width;
1378 fMiterLimit = p.getStrokeMiter();
1379 fResScale = 1;
1380 fCap = (uint8_t)p.getStrokeCap();
1381 fJoin = (uint8_t)p.getStrokeJoin();
1382 fDoFill = SkToU8(p.getStyle() == SkPaint::kStrokeAndFill_Style);
1383}
int32_t width

Member Function Documentation

◆ getCap()

SkPaint::Cap SkStroke::getCap ( ) const
inline

Definition at line 42 of file SkStroke.h.

42{ return (SkPaint::Cap)fCap; }

◆ getDoFill()

bool SkStroke::getDoFill ( ) const
inline

Definition at line 51 of file SkStroke.h.

51{ return SkToBool(fDoFill); }
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35

◆ getJoin()

SkPaint::Join SkStroke::getJoin ( ) const
inline

Definition at line 45 of file SkStroke.h.

45{ return (SkPaint::Join)fJoin; }

◆ getResScale()

SkScalar SkStroke::getResScale ( ) const
inline

ResScale is the "intended" resolution for the output. Default is 1.0. Larger values (res > 1) indicate that the result should be more precise, since it will be zoomed up, and small errors will be magnified. Smaller values (0 < res < 1) indicate that the result can be less precise, since it will be zoomed down, and small errors may be invisible.

Definition at line 62 of file SkStroke.h.

62{ return fResScale; }

◆ setCap()

void SkStroke::setCap ( SkPaint::Cap  cap)

Definition at line 1395 of file SkStroke.cpp.

1395 {
1396 SkASSERT((unsigned)cap < SkPaint::kCapCount);
1397 fCap = SkToU8(cap);
1398}
#define SkASSERT(cond)
Definition: SkAssert.h:116
static constexpr int kCapCount
Definition: SkPaint.h:343

◆ setDoFill()

void SkStroke::setDoFill ( bool  doFill)
inline

Definition at line 52 of file SkStroke.h.

52{ fDoFill = SkToU8(doFill); }

◆ setJoin()

void SkStroke::setJoin ( SkPaint::Join  join)

Definition at line 1400 of file SkStroke.cpp.

1400 {
1401 SkASSERT((unsigned)join < SkPaint::kJoinCount);
1402 fJoin = SkToU8(join);
1403}
static constexpr int kJoinCount
Definition: SkPaint.h:368
static SkString join(const CommandLineFlags::StringArray &)
Definition: skpbench.cpp:741

◆ setMiterLimit()

void SkStroke::setMiterLimit ( SkScalar  miterLimit)

Definition at line 1390 of file SkStroke.cpp.

1390 {
1391 SkASSERT(miterLimit >= 0);
1392 fMiterLimit = miterLimit;
1393}

◆ setResScale()

void SkStroke::setResScale ( SkScalar  rs)
inline

Definition at line 63 of file SkStroke.h.

63 {
64 SkASSERT(rs > 0 && std::isfinite(rs));
65 fResScale = rs;
66 }
SINT bool isfinite(const Vec< N, T > &v)
Definition: SkVx.h:1003

◆ setWidth()

void SkStroke::setWidth ( SkScalar  width)

Definition at line 1385 of file SkStroke.cpp.

1385 {
1386 SkASSERT(width >= 0);
1387 fWidth = width;
1388}

◆ strokePath()

void SkStroke::strokePath ( const SkPath path,
SkPath dst 
) const

Definition at line 1433 of file SkStroke.cpp.

1433 {
1434 SkASSERT(dst);
1435
1436 SkScalar radius = SkScalarHalf(fWidth);
1437
1438 AutoTmpPath tmp(src, &dst);
1439
1440 if (radius <= 0) {
1441 return;
1442 }
1443
1444 // If src is really a rect, call our specialty strokeRect() method
1445 {
1446 SkRect rect;
1447 bool isClosed = false;
1449 if (src.isRect(&rect, &isClosed, &dir) && isClosed) {
1450 this->strokeRect(rect, dst, dir);
1451 // our answer should preserve the inverseness of the src
1452 if (src.isInverseFillType()) {
1453 SkASSERT(!dst->isInverseFillType());
1454 dst->toggleInverseFillType();
1455 }
1456 return;
1457 }
1458 }
1459
1460 // We can always ignore centers for stroke and fill convex line-only paths
1461 // TODO: remove the line-only restriction
1462 bool ignoreCenter = fDoFill && (src.getSegmentMasks() == SkPath::kLine_SegmentMask) &&
1463 src.isLastContourClosed() && src.isConvex();
1464
1465 SkPathStroker stroker(src, radius, fMiterLimit, this->getCap(), this->getJoin(),
1466 fResScale, ignoreCenter);
1467 SkPath::Iter iter(src, false);
1468 SkPath::Verb lastSegment = SkPath::kMove_Verb;
1469
1470 for (;;) {
1471 SkPoint pts[4];
1472 switch (iter.next(pts)) {
1473 case SkPath::kMove_Verb:
1474 stroker.moveTo(pts[0]);
1475 break;
1476 case SkPath::kLine_Verb:
1477 stroker.lineTo(pts[1], &iter);
1478 lastSegment = SkPath::kLine_Verb;
1479 break;
1480 case SkPath::kQuad_Verb:
1481 stroker.quadTo(pts[1], pts[2]);
1482 lastSegment = SkPath::kQuad_Verb;
1483 break;
1484 case SkPath::kConic_Verb: {
1485 stroker.conicTo(pts[1], pts[2], iter.conicWeight());
1486 lastSegment = SkPath::kConic_Verb;
1487 } break;
1489 stroker.cubicTo(pts[1], pts[2], pts[3]);
1490 lastSegment = SkPath::kCubic_Verb;
1491 break;
1493 if (SkPaint::kButt_Cap != this->getCap()) {
1494 /* If the stroke consists of a moveTo followed by a close, treat it
1495 as if it were followed by a zero-length line. Lines without length
1496 can have square and round end caps. */
1497 if (stroker.hasOnlyMoveTo()) {
1498 stroker.lineTo(stroker.moveToPt());
1499 goto ZERO_LENGTH;
1500 }
1501 /* If the stroke consists of a moveTo followed by one or more zero-length
1502 verbs, then followed by a close, treat is as if it were followed by a
1503 zero-length line. Lines without length can have square & round end caps. */
1504 if (stroker.isCurrentContourEmpty()) {
1505 ZERO_LENGTH:
1506 lastSegment = SkPath::kLine_Verb;
1507 break;
1508 }
1509 }
1510 stroker.close(lastSegment == SkPath::kLine_Verb);
1511 break;
1512 case SkPath::kDone_Verb:
1513 goto DONE;
1514 }
1515 }
1516DONE:
1517 stroker.done(dst, lastSegment == SkPath::kLine_Verb);
1518
1519 if (fDoFill && !ignoreCenter) {
1521 dst->reverseAddPath(src);
1522 } else {
1523 dst->addPath(src);
1524 }
1525 } else {
1526 // Seems like we can assume that a 2-point src would always result in
1527 // a convex stroke, but testing has proved otherwise.
1528 // TODO: fix the stroker to make this assumption true (without making
1529 // it slower that the work that will be done in computeConvexity())
1530#if 0
1531 // this test results in a non-convex stroke :(
1532 static void test(SkCanvas* canvas) {
1533 SkPoint pts[] = { 146.333328, 192.333328, 300.333344, 293.333344 };
1534 SkPaint paint;
1535 paint.setStrokeWidth(7);
1536 paint.setStrokeCap(SkPaint::kRound_Cap);
1537 canvas->drawLine(pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, paint);
1538 }
1539#endif
1540#if 0
1541 if (2 == src.countPoints()) {
1542 dst->setIsConvex(true);
1543 }
1544#endif
1545 }
1546
1547 // our answer should preserve the inverseness of the src
1548 if (src.isInverseFillType()) {
1549 SkASSERT(!dst->isInverseFillType());
1550 dst->toggleInverseFillType();
1551 }
1552}
#define test(name)
SkPathDirection
Definition: SkPathTypes.h:34
#define SkScalarHalf(a)
Definition: SkScalar.h:75
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
Definition: SkCanvas.cpp:2700
@ kRound_Cap
adds circle
Definition: SkPaint.h:335
@ kButt_Cap
no stroke extension
Definition: SkPaint.h:334
static SkPathFirstDirection ComputeFirstDirection(const SkPath &)
Definition: SkPath.cpp:2627
@ kLine_SegmentMask
Definition: SkPath.h:1445
@ kClose_Verb
Definition: SkPath.h:1471
@ kMove_Verb
Definition: SkPath.h:1466
@ kConic_Verb
Definition: SkPath.h:1469
@ kDone_Verb
Definition: SkPath.h:1472
@ kCubic_Verb
Definition: SkPath.h:1470
@ kQuad_Verb
Definition: SkPath.h:1468
@ kLine_Verb
Definition: SkPath.h:1467
SkPaint::Cap getCap() const
Definition: SkStroke.h:42
void strokeRect(const SkRect &rect, SkPath *result, SkPathDirection=SkPathDirection::kCW) const
Definition: SkStroke.cpp:1584
SkPaint::Join getJoin() const
Definition: SkStroke.h:45
const Paint & paint
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
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 to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets dir
Definition: switches.h:145
dst
Definition: cp.py:12

◆ strokeRect()

void SkStroke::strokeRect ( const SkRect rect,
SkPath result,
SkPathDirection  dir = SkPathDirection::kCW 
) const

Stroke the specified rect, winding it in the specified direction..

Definition at line 1584 of file SkStroke.cpp.

1585 {
1586 SkASSERT(dst != nullptr);
1587 dst->reset();
1588
1589 SkScalar radius = SkScalarHalf(fWidth);
1590 if (radius <= 0) {
1591 return;
1592 }
1593
1594 SkScalar rw = origRect.width();
1595 SkScalar rh = origRect.height();
1596 if ((rw < 0) ^ (rh < 0)) {
1598 }
1599 SkRect rect(origRect);
1600 rect.sort();
1601 // reassign these, now that we know they'll be >= 0
1602 rw = rect.width();
1603 rh = rect.height();
1604
1605 SkRect r(rect);
1606 r.outset(radius, radius);
1607
1609 if (SkPaint::kMiter_Join == join && fMiterLimit < SK_ScalarSqrt2) {
1611 }
1612
1613 switch (join) {
1615 dst->addRect(r, dir);
1616 break;
1618 addBevel(dst, rect, r, dir);
1619 break;
1621 dst->addRoundRect(r, radius, radius, dir);
1622 break;
1623 default:
1624 break;
1625 }
1626
1627 if (fWidth < std::min(rw, rh) && !fDoFill) {
1628 r = rect;
1629 r.inset(radius, radius);
1630 dst->addRect(r, reverse_direction(dir));
1631 }
1632}
#define SK_ScalarSqrt2
Definition: SkScalar.h:20
static SkPathDirection reverse_direction(SkPathDirection dir)
Definition: SkStroke.cpp:1554
static void addBevel(SkPath *path, const SkRect &r, const SkRect &outer, SkPathDirection dir)
Definition: SkStroke.cpp:1559
@ kRound_Join
adds circle
Definition: SkPaint.h:360
@ kMiter_Join
extends to miter limit
Definition: SkPaint.h:359
@ kBevel_Join
connects outside edges
Definition: SkPaint.h:361
static float min(float r, float g, float b)
Definition: hsl.cpp:48

Friends And Related Function Documentation

◆ SkPaint

friend class SkPaint
friend

Definition at line 83 of file SkStroke.h.


The documentation for this class was generated from the following files: