Another fix for dash line thickness.

Use the device space offset from the dash centerline for
antialiasing in y direction.

Bug: chromium:1049028

Change-Id: Ib6363579680d05cbf1fe34795695422baeca7065
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/288764
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2020-05-08 15:32:28 -04:00 committed by Skia Commit-Bot
parent c9911527d2
commit bf1904fd48
2 changed files with 34 additions and 29 deletions

View File

@ -585,7 +585,7 @@ DEF_SIMPLE_GM(dash_line_zero_off_interval, canvas, 160, 330) {
}
}
DEF_SIMPLE_GM(thin_aa_dash_lines, canvas, 110, 110) {
DEF_SIMPLE_GM(thin_aa_dash_lines, canvas, 330, 110) {
SkPaint paint;
static constexpr SkScalar kIntervals[] = {10, 5};
paint.setPathEffect(SkDashPathEffect::Make(kIntervals, SK_ARRAY_COUNT(kIntervals), 0.f));
@ -596,9 +596,13 @@ DEF_SIMPLE_GM(thin_aa_dash_lines, canvas, 110, 110) {
// We will draw a grid of horiz/vertical lines that pass through each other's off intervals.
static constexpr SkScalar kStep = kIntervals[0] + kIntervals[1];
canvas->translate(kIntervals[1], kIntervals[1]);
for (SkScalar x = -.5f*kIntervals[1]; x < 105; x += (kStep + kSubstep)) {
canvas->drawLine({x, 0}, {x, 100}, paint);
canvas->drawLine({0, x}, {100, x}, paint);
for (auto c : {SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap}) {
paint.setStrokeCap(c);
for (SkScalar x = -.5f*kIntervals[1]; x < 105; x += (kStep + kSubstep)) {
canvas->drawLine({x, 0}, {x, 100}, paint);
canvas->drawLine({0, x}, {100, x}, paint);
}
canvas->translate(110, 0);
}
}

View File

@ -152,13 +152,21 @@ enum DashCap {
kNonRound_DashCap,
};
static void setup_dashed_rect(const SkRect& rect, GrVertexWriter& vertices, const SkMatrix& matrix,
SkScalar offset, SkScalar bloatX, SkScalar bloatY, SkScalar len,
SkScalar stroke, SkScalar startInterval, SkScalar endInterval,
SkScalar strokeWidth, DashCap cap) {
static void setup_dashed_rect(const SkRect& rect,
GrVertexWriter& vertices,
const SkMatrix& matrix,
SkScalar offset,
SkScalar bloatX,
SkScalar len,
SkScalar startInterval,
SkScalar endInterval,
SkScalar strokeWidth,
DashCap cap) {
SkScalar intervalLength = startInterval + endInterval;
SkRect dashRect = { offset - bloatX, -stroke - bloatY,
offset + len + bloatX, stroke + bloatY };
// 'dashRect' gets interpolated over the rendered 'rect'. For y we want the perpendicular signed
// distance from the stroke center line in device space.
SkRect dashRect = { offset - bloatX, -rect.height()/2.f,
offset + len + bloatX, rect.height()/2.f};
if (kRound_DashCap == cap) {
SkScalar radius = SkScalarHalf(strokeWidth) - 0.5f;
@ -318,9 +326,7 @@ private:
SkScalar fStartOffset;
SkScalar fStrokeWidth;
SkScalar fLineLength;
SkScalar fHalfDevStroke;
SkScalar fDevBloatX;
SkScalar fDevBloatY;
bool fLineDone;
bool fHasStartRect;
bool fHasEndRect;
@ -596,8 +602,6 @@ private:
draw.fStartOffset = startOffset;
draw.fDevBloatX = devBloatX;
draw.fDevBloatY = devBloatY;
draw.fHalfDevStroke = halfDevStroke;
draw.fStrokeWidth = strokeWidth;
draw.fHasStartRect = hasStartRect;
draw.fLineDone = lineDone;
@ -620,11 +624,10 @@ private:
if (!draws[i].fLineDone) {
if (fullDash) {
setup_dashed_rect(
rects[rectIndex], vertices, geom.fSrcRotInv,
draws[i].fStartOffset, draws[i].fDevBloatX, draws[i].fDevBloatY,
draws[i].fLineLength, draws[i].fHalfDevStroke, draws[i].fIntervals[0],
draws[i].fIntervals[1], draws[i].fStrokeWidth, capType);
setup_dashed_rect(rects[rectIndex], vertices, geom.fSrcRotInv,
draws[i].fStartOffset, draws[i].fDevBloatX,
draws[i].fLineLength, draws[i].fIntervals[0],
draws[i].fIntervals[1], draws[i].fStrokeWidth, capType);
} else {
vertices.writeQuad(GrQuad::MakeFromRect(rects[rectIndex], geom.fSrcRotInv));
}
@ -633,11 +636,10 @@ private:
if (draws[i].fHasStartRect) {
if (fullDash) {
setup_dashed_rect(
rects[rectIndex], vertices, geom.fSrcRotInv,
draws[i].fStartOffset, draws[i].fDevBloatX, draws[i].fDevBloatY,
draws[i].fIntervals[0], draws[i].fHalfDevStroke, draws[i].fIntervals[0],
draws[i].fIntervals[1], draws[i].fStrokeWidth, capType);
setup_dashed_rect(rects[rectIndex], vertices, geom.fSrcRotInv,
draws[i].fStartOffset, draws[i].fDevBloatX,
draws[i].fIntervals[0], draws[i].fIntervals[0],
draws[i].fIntervals[1], draws[i].fStrokeWidth, capType);
} else {
vertices.writeQuad(GrQuad::MakeFromRect(rects[rectIndex], geom.fSrcRotInv));
}
@ -646,11 +648,10 @@ private:
if (draws[i].fHasEndRect) {
if (fullDash) {
setup_dashed_rect(
rects[rectIndex], vertices, geom.fSrcRotInv,
draws[i].fStartOffset, draws[i].fDevBloatX, draws[i].fDevBloatY,
draws[i].fIntervals[0], draws[i].fHalfDevStroke, draws[i].fIntervals[0],
draws[i].fIntervals[1], draws[i].fStrokeWidth, capType);
setup_dashed_rect(rects[rectIndex], vertices, geom.fSrcRotInv,
draws[i].fStartOffset, draws[i].fDevBloatX,
draws[i].fIntervals[0], draws[i].fIntervals[0],
draws[i].fIntervals[1], draws[i].fStrokeWidth, capType);
} else {
vertices.writeQuad(GrQuad::MakeFromRect(rects[rectIndex], geom.fSrcRotInv));
}