//
// For circular roundrects, in the case where the stroke width is greater than twice
// the corner radius (overstroke), we add additional geometry to mark out the rectangle
-// in the center:
+// in the center. The shared vertices are duplicated so we can set a different outer radius
+// for the fill calculation.
// ____________
// |_|________|_|
// | |\ ____ /| |
static const uint16_t gRRectOverstrokeIndices[] = {
// overstroke quads
// we place this at the beginning so that we can skip these indices when rendering normally
- 5, 6, 17, 5, 17, 16,
- 17, 6, 10, 17, 10, 19,
- 10, 9, 18, 10, 18, 19,
- 18, 9, 5, 18, 5, 16,
+ 16, 17, 19, 16, 19, 18,
+ 19, 17, 23, 19, 23, 21,
+ 21, 23, 22, 21, 22, 20,
+ 22, 16, 18, 22, 18, 20,
// corners
0, 1, 5, 0, 5, 4,
static const int kIndicesPerFillRRect = kIndicesPerOverstrokeRRect - 6*4 + 6;
static const int kIndicesPerStrokeRRect = kIndicesPerFillRRect - 6;
static const int kVertsPerStandardRRect = 16;
-static const int kVertsPerOverstrokeRRect = 20;
+static const int kVertsPerOverstrokeRRect = 24;
static const int kNumRRectsInIndexBuffer = 256;
enum RRectType {
verts++;
}
// Add the additional vertices for overstroked rrects.
+ // Effectively this is an additional rrect, drawn inside out,
+ // with outerRadius == -innerRadius. This will give us correct AA in the center.
//
// Note that args.fInnerRadius is negative in this case.
// Also, the offset is a constant vector pointing to the right, which guarantees
// that the distance value along the inner rectangle is constant, which
// is what we want to get nice anti-aliasing.
if (kOverstroke_RRectType == fType) {
- // outerRadius = originalOuter + 0.5, and innerRadius = originalInner - 0.5.
- // What we want is originalOuter - originalInner + 0.5, so we subtract 0.5.
- SkScalar inset = outerRadius - args.fInnerRadius - SK_ScalarHalf;
+ verts->fPos = SkPoint::Make(bounds.fLeft + outerRadius, yCoords[1]);
+ verts->fColor = color;
+ verts->fOffset = SkPoint::Make(0, 0);
+ verts->fOuterRadius = -args.fInnerRadius;
+ verts->fInnerRadius = innerRadius;
+ verts++;
+
+ verts->fPos = SkPoint::Make(bounds.fRight - outerRadius, yCoords[1]);
+ verts->fColor = color;
+ verts->fOffset = SkPoint::Make(0, 0);
+ verts->fOuterRadius = -args.fInnerRadius;
+ verts->fInnerRadius = innerRadius;
+ verts++;
+
+ SkScalar inset = outerRadius - args.fInnerRadius;
verts->fPos = SkPoint::Make(bounds.fLeft + inset,
bounds.fTop + inset);
verts->fColor = color;
verts->fOffset = SkPoint::Make(1, 0);
- verts->fOuterRadius = outerRadius;
+ verts->fOuterRadius = -args.fInnerRadius;
verts->fInnerRadius = innerRadius;
verts++;
bounds.fTop + inset);
verts->fColor = color;
verts->fOffset = SkPoint::Make(1, 0);
- verts->fOuterRadius = outerRadius;
+ verts->fOuterRadius = -args.fInnerRadius;
verts->fInnerRadius = innerRadius;
verts++;
bounds.fBottom - inset);
verts->fColor = color;
verts->fOffset = SkPoint::Make(1, 0);
- verts->fOuterRadius = outerRadius;
+ verts->fOuterRadius = -args.fInnerRadius;
verts->fInnerRadius = innerRadius;
verts++;
bounds.fBottom - inset);
verts->fColor = color;
verts->fOffset = SkPoint::Make(1, 0);
- verts->fOuterRadius = outerRadius;
+ verts->fOuterRadius = -args.fInnerRadius;
+ verts->fInnerRadius = innerRadius;
+ verts++;
+
+ verts->fPos = SkPoint::Make(bounds.fLeft + outerRadius, yCoords[2]);
+ verts->fColor = color;
+ verts->fOffset = SkPoint::Make(0, 0);
+ verts->fOuterRadius = -args.fInnerRadius;
+ verts->fInnerRadius = innerRadius;
+ verts++;
+
+ verts->fPos = SkPoint::Make(bounds.fRight - outerRadius, yCoords[2]);
+ verts->fColor = color;
+ verts->fOffset = SkPoint::Make(0, 0);
+ verts->fOuterRadius = -args.fInnerRadius;
verts->fInnerRadius = innerRadius;
verts++;
}