// new antialiased mesh from those vertices.
void boundary_to_aa_mesh(EdgeList* boundary, VertexList* mesh, Comparator& c, SkChunkAlloc& alloc) {
- EdgeList outerContour;
Edge* prevEdge = boundary->fTail;
float radius = 0.5f;
double offset = radius * sqrt(prevEdge->fLine.magSq()) * prevEdge->fWinding;
prevOuter.fC += offset;
VertexList innerVertices;
VertexList outerVertices;
- SkScalar innerCount = SK_Scalar1, outerCount = SK_Scalar1;
+ SkVector prevNormal;
+ get_edge_normal(prevEdge, &prevNormal);
for (Edge* e = boundary->fHead; e != nullptr; e = e->fRight) {
double offset = radius * sqrt(e->fLine.magSq()) * e->fWinding;
Line inner(e->fTop, e->fBottom);
Line outer(e->fTop, e->fBottom);
outer.fC += offset;
SkPoint innerPoint, outerPoint;
+ SkVector normal;
+ get_edge_normal(e, &normal);
if (prevInner.intersect(inner, &innerPoint) &&
prevOuter.intersect(outer, &outerPoint)) {
- Vertex* innerVertex = ALLOC_NEW(Vertex, (innerPoint, 255), alloc);
- Vertex* outerVertex = ALLOC_NEW(Vertex, (outerPoint, 0), alloc);
- if (innerVertices.fTail && outerVertices.fTail) {
- Edge innerEdge(innerVertices.fTail, innerVertex, 1, Edge::Type::kInner);
- Edge outerEdge(outerVertices.fTail, outerVertex, 1, Edge::Type::kInner);
- SkVector innerNormal;
- get_edge_normal(&innerEdge, &innerNormal);
- SkVector outerNormal;
- get_edge_normal(&outerEdge, &outerNormal);
- SkVector normal;
- get_edge_normal(prevEdge, &normal);
- if (normal.dot(innerNormal) < 0) {
- innerPoint += innerVertices.fTail->fPoint * innerCount;
- innerCount++;
- innerPoint *= SkScalarInvert(innerCount);
- innerVertices.fTail->fPoint = innerVertex->fPoint = innerPoint;
- } else {
- innerCount = SK_Scalar1;
- }
- if (normal.dot(outerNormal) < 0) {
- outerPoint += outerVertices.fTail->fPoint * outerCount;
- outerCount++;
- outerPoint *= SkScalarInvert(outerCount);
- outerVertices.fTail->fPoint = outerVertex->fPoint = outerPoint;
- } else {
- outerCount = SK_Scalar1;
- }
+ // cos(theta) < -0.999 implies a miter angle of ~2.5 degrees,
+ // below which we'll bevel the outer edges.
+ if (prevNormal.dot(normal) < -0.999) {
+ SkPoint p = e->fWinding > 0 ? e->fTop->fPoint : e->fBottom->fPoint;
+ SkPoint outerPoint1 = p - prevNormal * radius;
+ SkPoint outerPoint2 = p - normal * radius;
+ innerVertices.append(ALLOC_NEW(Vertex, (innerPoint, 255), alloc));
+ innerVertices.append(ALLOC_NEW(Vertex, (innerPoint, 255), alloc));
+ outerVertices.append(ALLOC_NEW(Vertex, (outerPoint1, 0), alloc));
+ outerVertices.append(ALLOC_NEW(Vertex, (outerPoint2, 0), alloc));
+ } else {
+ innerVertices.append(ALLOC_NEW(Vertex, (innerPoint, 255), alloc));
+ outerVertices.append(ALLOC_NEW(Vertex, (outerPoint, 0), alloc));
}
- innerVertices.append(innerVertex);
- outerVertices.append(outerVertex);
- prevEdge = e;
}
prevInner = inner;
prevOuter = outer;
+ prevEdge = e;
+ prevNormal = normal;
}
innerVertices.close();
outerVertices.close();
Vertex* innerVertex = innerVertices.fHead;
Vertex* outerVertex = outerVertices.fHead;
- // Alternate clockwise and counterclockwise polys, so the tesselator
- // doesn't cancel out the interior edges.
if (!innerVertex || !outerVertex) {
return;
}