Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/core/SkStroke.cpp

Issue 1309753002: experiment with zero-length round capped line segments (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: add overall documentation with paint caps Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkPathMeasure.cpp ('k') | src/utils/SkDashPath.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2008 The Android Open Source Project 2 * Copyright 2008 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkStrokerPriv.h" 8 #include "SkStrokerPriv.h"
9 #include "SkGeometry.h" 9 #include "SkGeometry.h"
10 #include "SkPathPriv.h" 10 #include "SkPathPriv.h"
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 return true; 114 return true;
115 } 115 }
116 }; 116 };
117 117
118 class SkPathStroker { 118 class SkPathStroker {
119 public: 119 public:
120 SkPathStroker(const SkPath& src, 120 SkPathStroker(const SkPath& src,
121 SkScalar radius, SkScalar miterLimit, SkPaint::Cap, 121 SkScalar radius, SkScalar miterLimit, SkPaint::Cap,
122 SkPaint::Join, SkScalar resScale); 122 SkPaint::Join, SkScalar resScale);
123 123
124 bool hasOnlyMoveTo() const { return 0 == fSegmentCount; }
125 SkPoint moveToPt() const { return fFirstPt; }
126
124 void moveTo(const SkPoint&); 127 void moveTo(const SkPoint&);
125 void lineTo(const SkPoint&); 128 void lineTo(const SkPoint&);
126 void quadTo(const SkPoint&, const SkPoint&); 129 void quadTo(const SkPoint&, const SkPoint&);
127 void conicTo(const SkPoint&, const SkPoint&, SkScalar weight); 130 void conicTo(const SkPoint&, const SkPoint&, SkScalar weight);
128 void cubicTo(const SkPoint&, const SkPoint&, const SkPoint&); 131 void cubicTo(const SkPoint&, const SkPoint&, const SkPoint&);
129 void close(bool isLine) { this->finishContour(true, isLine); } 132 void close(bool isLine) { this->finishContour(true, isLine); }
130 133
131 void done(SkPath* dst, bool isLine) { 134 void done(SkPath* dst, bool isLine) {
132 this->finishContour(false, isLine); 135 this->finishContour(false, isLine);
133 fOuter.addPath(fExtra); 136 fOuter.addPath(fExtra);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 /////////////////////////////////////////////////////////////////////////////// 238 ///////////////////////////////////////////////////////////////////////////////
236 239
237 bool SkPathStroker::preJoinTo(const SkPoint& currPt, SkVector* normal, 240 bool SkPathStroker::preJoinTo(const SkPoint& currPt, SkVector* normal,
238 SkVector* unitNormal, bool currIsLine) { 241 SkVector* unitNormal, bool currIsLine) {
239 SkASSERT(fSegmentCount >= 0); 242 SkASSERT(fSegmentCount >= 0);
240 243
241 SkScalar prevX = fPrevPt.fX; 244 SkScalar prevX = fPrevPt.fX;
242 SkScalar prevY = fPrevPt.fY; 245 SkScalar prevY = fPrevPt.fY;
243 246
244 if (!set_normal_unitnormal(fPrevPt, currPt, fRadius, normal, unitNormal)) { 247 if (!set_normal_unitnormal(fPrevPt, currPt, fRadius, normal, unitNormal)) {
245 return false; 248 if (SkStrokerPriv::CapFactory(SkPaint::kButt_Cap) == fCapper) {
249 return false;
250 }
251 /* Square caps and round caps draw even if the segment length is zero.
252 Since the zero length segment has no direction, set the orientation
253 to upright as the default orientation */
254 normal->set(fRadius, 0);
255 unitNormal->set(1, 0);
246 } 256 }
247 257
248 if (fSegmentCount == 0) { 258 if (fSegmentCount == 0) {
249 fFirstNormal = *normal; 259 fFirstNormal = *normal;
250 fFirstUnitNormal = *unitNormal; 260 fFirstUnitNormal = *unitNormal;
251 fFirstOuterPt.set(prevX + normal->fX, prevY + normal->fY); 261 fFirstOuterPt.set(prevX + normal->fX, prevY + normal->fY);
252 262
253 fOuter.moveTo(fFirstOuterPt.fX, fFirstOuterPt.fY); 263 fOuter.moveTo(fFirstOuterPt.fX, fFirstOuterPt.fY);
254 fInner.moveTo(prevX - normal->fX, prevY - normal->fY); 264 fInner.moveTo(prevX - normal->fX, prevY - normal->fY);
255 } else { // we have a previous segment 265 } else { // we have a previous segment
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 fSegmentCount = 0; 359 fSegmentCount = 0;
350 fFirstPt = fPrevPt = pt; 360 fFirstPt = fPrevPt = pt;
351 } 361 }
352 362
353 void SkPathStroker::line_to(const SkPoint& currPt, const SkVector& normal) { 363 void SkPathStroker::line_to(const SkPoint& currPt, const SkVector& normal) {
354 fOuter.lineTo(currPt.fX + normal.fX, currPt.fY + normal.fY); 364 fOuter.lineTo(currPt.fX + normal.fX, currPt.fY + normal.fY);
355 fInner.lineTo(currPt.fX - normal.fX, currPt.fY - normal.fY); 365 fInner.lineTo(currPt.fX - normal.fX, currPt.fY - normal.fY);
356 } 366 }
357 367
358 void SkPathStroker::lineTo(const SkPoint& currPt) { 368 void SkPathStroker::lineTo(const SkPoint& currPt) {
359 if (SkPath::IsLineDegenerate(fPrevPt, currPt, false)) { 369 if (SkStrokerPriv::CapFactory(SkPaint::kButt_Cap) == fCapper
370 && SkPath::IsLineDegenerate(fPrevPt, currPt, false)) {
360 return; 371 return;
361 } 372 }
362 SkVector normal, unitNormal; 373 SkVector normal, unitNormal;
363 374
364 if (!this->preJoinTo(currPt, &normal, &unitNormal, true)) { 375 if (!this->preJoinTo(currPt, &normal, &unitNormal, true)) {
365 return; 376 return;
366 } 377 }
367 this->line_to(currPt, normal); 378 this->line_to(currPt, normal);
368 this->postJoinTo(currPt, normal, unitNormal); 379 this->postJoinTo(currPt, normal, unitNormal);
369 } 380 }
(...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after
1327 case SkPath::kConic_Verb: { 1338 case SkPath::kConic_Verb: {
1328 stroker.conicTo(pts[1], pts[2], iter.conicWeight()); 1339 stroker.conicTo(pts[1], pts[2], iter.conicWeight());
1329 lastSegment = SkPath::kConic_Verb; 1340 lastSegment = SkPath::kConic_Verb;
1330 break; 1341 break;
1331 } break; 1342 } break;
1332 case SkPath::kCubic_Verb: 1343 case SkPath::kCubic_Verb:
1333 stroker.cubicTo(pts[1], pts[2], pts[3]); 1344 stroker.cubicTo(pts[1], pts[2], pts[3]);
1334 lastSegment = SkPath::kCubic_Verb; 1345 lastSegment = SkPath::kCubic_Verb;
1335 break; 1346 break;
1336 case SkPath::kClose_Verb: 1347 case SkPath::kClose_Verb:
1348 if (stroker.hasOnlyMoveTo() && SkPaint::kButt_Cap != this->getCa p()) {
1349 /* If the stroke consists of a moveTo followed by a close, t reat it
1350 as if it were followed by a zero-length line. Lines witho ut length
1351 can have square and round end caps. */
1352 stroker.lineTo(stroker.moveToPt());
1353 lastSegment = SkPath::kLine_Verb;
1354 break;
1355 }
1337 stroker.close(lastSegment == SkPath::kLine_Verb); 1356 stroker.close(lastSegment == SkPath::kLine_Verb);
1338 break; 1357 break;
1339 case SkPath::kDone_Verb: 1358 case SkPath::kDone_Verb:
1340 goto DONE; 1359 goto DONE;
1341 } 1360 }
1342 } 1361 }
1343 DONE: 1362 DONE:
1344 stroker.done(dst, lastSegment == SkPath::kLine_Verb); 1363 stroker.done(dst, lastSegment == SkPath::kLine_Verb);
1345 1364
1346 if (fDoFill) { 1365 if (fDoFill) {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 default: 1469 default:
1451 break; 1470 break;
1452 } 1471 }
1453 1472
1454 if (fWidth < SkMinScalar(rw, rh) && !fDoFill) { 1473 if (fWidth < SkMinScalar(rw, rh) && !fDoFill) {
1455 r = rect; 1474 r = rect;
1456 r.inset(radius, radius); 1475 r.inset(radius, radius);
1457 dst->addRect(r, reverse_direction(dir)); 1476 dst->addRect(r, reverse_direction(dir));
1458 } 1477 }
1459 } 1478 }
OLDNEW
« no previous file with comments | « src/core/SkPathMeasure.cpp ('k') | src/utils/SkDashPath.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698