Merge "Add conic support for Path#approximate" into oc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
ebd44d0076
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "SkPath.h"
|
||||
#include "SkPathOps.h"
|
||||
#include "SkGeometry.h" // WARNING: Internal Skia Header
|
||||
|
||||
#include <Caches.h>
|
||||
#include <vector>
|
||||
@@ -355,8 +356,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static void createVerbSegments(SkPath::Verb verb, const SkPoint* points,
|
||||
std::vector<SkPoint>& segmentPoints, std::vector<float>& lengths, float errorSquared) {
|
||||
static void createVerbSegments(const SkPath::Iter& pathIter, SkPath::Verb verb,
|
||||
const SkPoint* points, std::vector<SkPoint>& segmentPoints,
|
||||
std::vector<float>& lengths, float errorSquared, float errorConic) {
|
||||
switch (verb) {
|
||||
case SkPath::kMove_Verb:
|
||||
addMove(segmentPoints, lengths, points[0]);
|
||||
@@ -375,8 +377,27 @@ public:
|
||||
addBezier(points, cubicBezierCalculation, segmentPoints, lengths,
|
||||
errorSquared, true);
|
||||
break;
|
||||
case SkPath::kConic_Verb: {
|
||||
SkAutoConicToQuads converter;
|
||||
const SkPoint* quads = converter.computeQuads(
|
||||
points, pathIter.conicWeight(), errorConic);
|
||||
for (int i = 0; i < converter.countQuads(); i++) {
|
||||
// Note: offset each subsequent quad by 2, since end points are shared
|
||||
const SkPoint* quad = quads + i * 2;
|
||||
addBezier(quad, quadraticBezierCalculation, segmentPoints, lengths,
|
||||
errorConic, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Leave element as NULL, Conic sections are not supported.
|
||||
static_assert(SkPath::kMove_Verb == 0
|
||||
&& SkPath::kLine_Verb == 1
|
||||
&& SkPath::kQuad_Verb == 2
|
||||
&& SkPath::kConic_Verb == 3
|
||||
&& SkPath::kCubic_Verb == 4
|
||||
&& SkPath::kClose_Verb == 5
|
||||
&& SkPath::kDone_Verb == 6,
|
||||
"Path enum changed, new types may have been added.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -398,9 +419,11 @@ public:
|
||||
std::vector<SkPoint> segmentPoints;
|
||||
std::vector<float> lengths;
|
||||
float errorSquared = acceptableError * acceptableError;
|
||||
float errorConic = acceptableError / 2; // somewhat arbitrary
|
||||
|
||||
while ((verb = pathIter.next(points, false)) != SkPath::kDone_Verb) {
|
||||
createVerbSegments(verb, points, segmentPoints, lengths, errorSquared);
|
||||
createVerbSegments(pathIter, verb, points, segmentPoints, lengths,
|
||||
errorSquared, errorConic);
|
||||
}
|
||||
|
||||
if (segmentPoints.empty()) {
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
package android.graphics;
|
||||
|
||||
import android.annotation.FloatRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.Size;
|
||||
|
||||
import dalvik.annotation.optimization.CriticalNative;
|
||||
import dalvik.annotation.optimization.FastNative;
|
||||
@@ -805,7 +807,12 @@ public class Path {
|
||||
* the error is less than half a pixel.
|
||||
* @return An array of components for points approximating the Path.
|
||||
*/
|
||||
public float[] approximate(float acceptableError) {
|
||||
@NonNull
|
||||
@Size(min = 6, multiple = 3)
|
||||
public float[] approximate(@FloatRange(from = 0) float acceptableError) {
|
||||
if (acceptableError < 0) {
|
||||
throw new IllegalArgumentException("AcceptableError must be greater than or equal to 0");
|
||||
}
|
||||
return nApproximate(mNativePath, acceptableError);
|
||||
}
|
||||
|
||||
|
||||
@@ -1005,6 +1005,14 @@ bool PathTessellator::approximatePathOutlineVertices(const SkPath& path, bool fo
|
||||
break;
|
||||
}
|
||||
default:
|
||||
static_assert(SkPath::kMove_Verb == 0
|
||||
&& SkPath::kLine_Verb == 1
|
||||
&& SkPath::kQuad_Verb == 2
|
||||
&& SkPath::kConic_Verb == 3
|
||||
&& SkPath::kCubic_Verb == 4
|
||||
&& SkPath::kClose_Verb == 5
|
||||
&& SkPath::kDone_Verb == 6,
|
||||
"Path enum changed, new types may have been added");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user