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

Unified Diff: src/pathops/SkOpBuilder.cpp

Issue 853223002: new files for pathops geometric intersection (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: remove visualizer tool so cl contains only pure adds Created 5 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/pathops/SkOpCoincidence.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pathops/SkOpBuilder.cpp
diff --git a/src/pathops/SkOpBuilder.cpp b/src/pathops/SkOpBuilder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..489ad639c179b19046cf48941b1e7c7c2152cb99
--- /dev/null
+++ b/src/pathops/SkOpBuilder.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkMatrix.h"
+#include "SkPath.h"
+#include "SkPathOps.h"
+
+void SkOpBuilder::add(const SkPath& path, SkPathOp op) {
+ if (0 == fOps.count() && op != kUnion_PathOp) {
+ fPathRefs.push_back() = SkPath();
+ *fOps.append() = kUnion_PathOp;
+ }
+ fPathRefs.push_back() = path;
+ *fOps.append() = op;
+}
+
+void SkOpBuilder::reset() {
+ fPathRefs.reset();
+ fOps.reset();
+}
+
+/* OPTIMIZATION: Union doesn't need to be all-or-nothing. A run of three or more convex
+ paths with union ops could be locally resolved and still improve over doing the
+ ops one at a time. */
+bool SkOpBuilder::resolve(SkPath* result) {
+ int count = fOps.count();
+ bool allUnion = true;
+ SkPath::Direction firstDir;
+ for (int index = 0; index < count; ++index) {
+ SkPath* test = &fPathRefs[index];
+ if (kUnion_PathOp != fOps[index] || test->isInverseFillType()) {
+ allUnion = false;
+ break;
+ }
+ // If all paths are convex, track direction, reversing as needed.
+ if (test->isConvex()) {
+ SkPath::Direction dir;
+ if (!test->cheapComputeDirection(&dir)) {
+ allUnion = false;
+ break;
+ }
+ if (index == 0) {
+ firstDir = dir;
+ } else if (firstDir != dir) {
+ SkPath temp;
+ temp.reverseAddPath(*test);
+ *test = temp;
+ }
+ continue;
+ }
+ // If the path is not convex but its bounds do not intersect the others, simplify is enough.
+ const SkRect& testBounds = test->getBounds();
+ for (int inner = 0; inner < index; ++inner) {
+ // OPTIMIZE: check to see if the contour bounds do not intersect other contour bounds?
+ if (SkRect::Intersects(fPathRefs[inner].getBounds(), testBounds)) {
+ allUnion = false;
+ break;
+ }
+ }
+ }
+ if (!allUnion) {
+ *result = fPathRefs[0];
+ for (int index = 1; index < count; ++index) {
+ if (!Op(*result, fPathRefs[index], fOps[index], result)) {
+ reset();
+ return false;
+ }
+ }
+ reset();
+ return true;
+ }
+ SkPath sum;
+ for (int index = 0; index < count; ++index) {
+ if (!Simplify(fPathRefs[index], &fPathRefs[index])) {
+ reset();
+ return false;
+ }
+ sum.addPath(fPathRefs[index]);
+ }
+ reset();
+ return Simplify(sum, result);
+}
« no previous file with comments | « no previous file | src/pathops/SkOpCoincidence.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698