Fix gpu line dashing when line is zero length but has cap

Bug: skia:7387
Change-Id: I49a023f395ab1539c80881f95242a4bdad6e70b3
Reviewed-on: https://skia-review.googlesource.com/79722
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
Greg Daniel 2017-12-07 15:00:06 -05:00 committed by Skia Commit-Bot
parent 8ab1cc477b
commit c96f9b5c14
2 changed files with 30 additions and 1 deletions

View File

@ -332,7 +332,7 @@ protected:
return SkString("dashing4");
}
SkISize onISize() { return SkISize::Make(640, 1050); }
SkISize onISize() { return SkISize::Make(640, 1100); }
virtual void onDraw(SkCanvas* canvas) {
constexpr struct {
@ -409,6 +409,16 @@ protected:
canvas->translate(0, SkIntToScalar(50));
paint.setStrokeCap(SkPaint::kSquare_Cap);
drawline(canvas, 0, 30, paint);
// Test we draw the cap when the line length is zero.
canvas->translate(0, SkIntToScalar(50));
paint.setStrokeCap(SkPaint::kRound_Cap);
paint.setColor(0xFF000000);
paint.setStrokeWidth(11);
drawline(canvas, 0, 30, paint, 0);
canvas->translate(SkIntToScalar(100), 0);
drawline(canvas, 1, 30, paint, 0);
}
};

View File

@ -88,6 +88,9 @@ struct DashCircleVertex {
static void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale,
const SkMatrix& viewMatrix, const SkPoint pts[2]) {
SkVector vecSrc = pts[1] - pts[0];
if (pts[1] == pts[0]) {
vecSrc.set(1.0, 0.0);
}
SkScalar magSrc = vecSrc.length();
SkScalar invSrc = magSrc ? SkScalarInvert(magSrc) : 0;
vecSrc.scale(invSrc);
@ -107,6 +110,9 @@ static void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale,
// Stores the rotation matrix in rotMatrix, and the mapped points in ptsRot
static void align_to_x_axis(const SkPoint pts[2], SkMatrix* rotMatrix, SkPoint ptsRot[2] = nullptr) {
SkVector vec = pts[1] - pts[0];
if (pts[1] == pts[0]) {
vec.set(1.0, 0.0);
}
SkScalar mag = vec.length();
SkScalar inv = mag ? SkScalarInvert(mag) : 0;
@ -491,6 +497,19 @@ private:
}
}
if (draw.fPtsRot[0].fX == draw.fPtsRot[1].fX &&
(0 != endAdj || 0 == startAdj) &&
hasCap) {
// At this point the fPtsRot[0]/[1] represent the start and end of the inner rect of
// dashes that we want to draw. The only way they can be equal is if the on interval
// is zero (or an edge case if the end of line ends at a full off interval, but this
// is handled as well). Thus if the on interval is zero then we need to draw a cap
// at this position if the stroke has caps. The spec says we only draw this point if
// point lies between [start of line, end of line). Thus we check if we are at the
// end (but not the start), and if so we don't draw the cap.
lineDone = false;
}
if (startAdj != 0) {
draw.fPhase = 0;
}