Index: src/utils/SkPatchUtils.cpp |
diff --git a/src/utils/SkPatchUtils.cpp b/src/utils/SkPatchUtils.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7dd0a09d974a5c1480bade68a30da4b73dcf03cc |
--- /dev/null |
+++ b/src/utils/SkPatchUtils.cpp |
@@ -0,0 +1,57 @@ |
+/* |
+ * 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 "SkPatchUtils.h" |
+ |
+#include "SkGeometry.h" |
+ |
+// size in pixels of each partition per axis, adjust this knob |
+static const int kPartitionSize = 30; |
+ |
+/** |
+ * Calculate the approximate arc length given a bezier curve's control points. |
+ */ |
+static SkScalar approx_arc_length(SkPoint* points, int count) { |
+ if (count < 2) { |
+ return 0; |
+ } |
+ SkScalar arcLength = 0; |
+ for (int i = 0; i < count - 1; i++) { |
+ arcLength += SkPoint::Distance(points[i], points[i + 1]); |
+ } |
+ return arcLength; |
+} |
+ |
+SkISize SkPatchUtils::GetLevelOfDetail(const SkPatch& patch, const SkMatrix* matrix) { |
+ |
+ SkPoint mapPts[12]; |
+ matrix->mapPoints(mapPts, patch.getControlPoints(), 12); |
+ |
+ // Approximate length of each cubic. |
+ SkPoint pts[4]; |
+ patch.getTopPoints(pts); |
+ matrix->mapPoints(pts, 4); |
+ SkScalar topLength = approx_arc_length(pts, 4); |
+ |
+ patch.getBottomPoints(pts); |
+ matrix->mapPoints(pts, 4); |
+ SkScalar bottomLength = approx_arc_length(pts, 4); |
+ |
+ patch.getLeftPoints(pts); |
+ matrix->mapPoints(pts, 4); |
+ SkScalar leftLength = approx_arc_length(pts, 4); |
+ |
+ patch.getRightPoints(pts); |
+ matrix->mapPoints(pts, 4); |
+ SkScalar rightLength = approx_arc_length(pts, 4); |
+ |
+ // Level of detail per axis, based on the larger side between top and bottom or left and right |
+ int lodX = static_cast<int>(SkMaxScalar(topLength, bottomLength) / kPartitionSize); |
+ int lodY = static_cast<int>(SkMaxScalar(leftLength, rightLength) / kPartitionSize); |
+ |
+ return SkISize::Make(SkMax32(4, lodX), SkMax32(4, lodY)); |
+} |