bool isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts,
bool* isClosed, Direction* direction) const;
+ // called by stroker to see if all points are equal and worthy of a cap
+ // equivalent to a short-circuit version of getBounds().isEmpty()
+ bool isZeroLength() const;
+
/** Returns if the path can return a bound at no cost (true) or will have to
perform some computation (false).
*/
return true;
}
+bool SkPath::isZeroLength() const {
+ int count = fPathRef->countPoints();
+ if (count < 2) {
+ return true;
+ }
+ const SkPoint* pts = fPathRef.get()->points();
+ const SkPoint& first = *pts;
+ for (int index = 1; index < count; ++index) {
+ if (first != pts[index]) {
+ return false;
+ }
+ }
+ return true;
+}
+
void SkPath::addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
Direction dir) {
assert_known_direction(dir);
SkScalar getResScale() const { return fResScale; }
+ bool isZeroLength() const {
+ return fInner.isZeroLength() && fOuter.isZeroLength();
+ }
+
private:
SkScalar fRadius;
SkScalar fInvMiterLimit;
lastSegment = SkPath::kCubic_Verb;
break;
case SkPath::kClose_Verb:
- if (stroker.hasOnlyMoveTo() && SkPaint::kButt_Cap != this->getCap()) {
+ if (SkPaint::kButt_Cap != this->getCap()) {
/* If the stroke consists of a moveTo followed by a close, treat it
as if it were followed by a zero-length line. Lines without length
can have square and round end caps. */
- stroker.lineTo(stroker.moveToPt());
- lastSegment = SkPath::kLine_Verb;
- break;
+ if (stroker.hasOnlyMoveTo()) {
+ stroker.lineTo(stroker.moveToPt());
+ goto ZERO_LENGTH;
+ }
+ /* If the stroke consists of a moveTo followed by one or more zero-length
+ verbs, then followed by a close, treat is as if it were followed by a
+ zero-length line. Lines without length can have square & round end caps. */
+ if (stroker.isZeroLength()) {
+ ZERO_LENGTH:
+ lastSegment = SkPath::kLine_Verb;
+ break;
+ }
}
stroker.close(lastSegment == SkPath::kLine_Verb);
break;