Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp

Issue 2737063002: Improve dashed line drawing (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/paint/BoxBorderPainter.h" 5 #include "core/paint/BoxBorderPainter.h"
6 6
7 #include "core/paint/BoxPainter.h" 7 #include "core/paint/BoxPainter.h"
8 #include "core/paint/ObjectPainter.h" 8 #include "core/paint/ObjectPainter.h"
9 #include "core/paint/PaintInfo.h" 9 #include "core/paint/PaintInfo.h"
10 #include "core/style/BorderEdge.h" 10 #include "core/style/BorderEdge.h"
(...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 1027
1028 graphicsContext.setStrokeColor(color); 1028 graphicsContext.setStrokeColor(color);
1029 1029
1030 if (!StrokeData::strokeIsDashed(thickness, borderStyle == BorderStyleDashed 1030 if (!StrokeData::strokeIsDashed(thickness, borderStyle == BorderStyleDashed
1031 ? DashedStroke 1031 ? DashedStroke
1032 : DottedStroke)) { 1032 : DottedStroke)) {
1033 drawWideDottedBoxSideFromPath(graphicsContext, centerlinePath, thickness); 1033 drawWideDottedBoxSideFromPath(graphicsContext, centerlinePath, thickness);
1034 return; 1034 return;
1035 } 1035 }
1036 1036
1037 // The stroke is doubled here because the provided path is the
1038 // outside edge of the border so half the stroke is clipped off.
1039 // The extra multiplier is so that the clipping mask can antialias 1037 // The extra multiplier is so that the clipping mask can antialias
1040 // the edges to prevent jaggies. 1038 // the edges to prevent jaggies.
1041 graphicsContext.setStrokeThickness(drawThickness * 1.1f); 1039 graphicsContext.setStrokeThickness(drawThickness * 1.1f);
1042 graphicsContext.setStrokeStyle( 1040 graphicsContext.setStrokeStyle(
1043 borderStyle == BorderStyleDashed ? DashedStroke : DottedStroke); 1041 borderStyle == BorderStyleDashed ? DashedStroke : DottedStroke);
1044 1042
1045 // If the number of dashes that fit in the path is odd and non-integral
1046 // then we will have an awkwardly-sized dash at the end of the path. To
1047 // try to avoid that here, we simply make the whitespace dashes ever so
1048 // slightly bigger.
1049 // TODO(schenney): This code for setting up the dash effect is trying to 1043 // TODO(schenney): This code for setting up the dash effect is trying to
1050 // do the same thing as StrokeData::setupPaintDashPathEffect and should be 1044 // do the same thing as StrokeData::setupPaintDashPathEffect and should be
1051 // refactored to re-use that code. It would require 1045 // refactored to re-use that code. It would require
1052 // GraphicsContext::strokePath to take a length parameter. 1046 // GraphicsContext::strokePath to take a length parameter.
1053 float dashLength = 1047 float dashLength = drawThickness;
1054 thickness * ((borderStyle == BorderStyleDashed) ? 3.0f : 1.0f);
1055 float gapLength = dashLength; 1048 float gapLength = dashLength;
1056 float numberOfDashes = centerlinePath.length() / dashLength; 1049 if (borderStyle == BorderStyleDashed) {
1050 dashLength *= StrokeData::dashLengthRatio(drawThickness);
1051 gapLength *= StrokeData::dashGapRatio(drawThickness);
1052 }
1053 float perDashLength = dashLength + gapLength;
1054 float pathLength = centerlinePath.length();
1057 // Don't try to show dashes if we have less than 2 dashes + 2 gaps. 1055 // Don't try to show dashes if we have less than 2 dashes + 2 gaps.
1058 // FIXME: should do this test per side. 1056 // FIXME: should do this test per side.
1059 if (numberOfDashes >= 4) { 1057 if (pathLength >= 2 * dashLength + gapLength) {
f(malita) 2017/03/08 16:51:56 nit: 2 * perDashLength
Stephen Chennney 2017/03/08 17:33:26 I changed this to be just 2 * dashLength because t
f(malita) 2017/03/08 17:48:02 Acknowledged.
1060 bool evenNumberOfFullDashes = !((int)numberOfDashes % 2); 1058 // Determine what number of dashes gives the minimum deviation from
1061 bool integralNumberOfDashes = !(numberOfDashes - (int)numberOfDashes); 1059 // idealGap between dashes. Set the gap to that width.
1062 if (!evenNumberOfFullDashes && !integralNumberOfDashes) { 1060 float minNumDashes = floorf((pathLength + gapLength) / perDashLength);
1063 float numberOfGaps = numberOfDashes / 2; 1061 float maxNumDashes = minNumDashes + 1;
1064 gapLength += (dashLength / numberOfGaps); 1062 float minGap = (pathLength - minNumDashes * gapLength) / (minNumDashes - 1);
f(malita) 2017/03/08 16:51:56 Shouldn't this use dashLength instead of gapLength
Stephen Chennney 2017/03/08 17:33:26 Yes. Fixed in the second patch.
f(malita) 2017/03/08 17:48:02 Acknowledged.
1065 } 1063 float maxGap = (pathLength - maxNumDashes * gapLength) / (maxNumDashes - 1);
f(malita) 2017/03/08 16:51:56 ditto
1064 auto gap =
1065 fabs(minGap - gapLength) < fabs(maxGap - gapLength) ? minGap : maxGap;
f(malita) 2017/03/08 16:51:56 Also, I can't quite work it out in my head but it
Stephen Chennney 2017/03/08 17:33:26 It might be. I'll look at it further. Even then, i
1066 1066
1067 DashArray lineDash; 1067 DashArray lineDash;
1068 lineDash.push_back(dashLength); 1068 lineDash.push_back(dashLength);
1069 lineDash.push_back(gapLength); 1069 lineDash.push_back(gap);
1070 graphicsContext.setLineDash(lineDash, dashLength); 1070 graphicsContext.setLineDash(lineDash, dashLength);
1071 } 1071 } else if (pathLength > dashLength) {
1072 // Exactly 2 dashes proportionally sized
1073 float multiplier = pathLength / (2 * dashLength + gapLength);
f(malita) 2017/03/08 16:51:56 should this be float multiplier = (pathLength + g
f(malita) 2017/03/08 16:51:56 nit: 2 * perDashLength
Stephen Chennney 2017/03/08 17:33:26 If there are 2 dashes at the endpoints then there
f(malita) 2017/03/08 17:48:02 Ah, yes, I was parsing that as 2 * (dashLength + g
1074 DashArray lineDash;
1075 lineDash.push_back(dashLength * multiplier);
1076 lineDash.push_back(gapLength * multiplier);
1077 graphicsContext.setLineDash(lineDash, 0);
1078 } // else don't dash at all
1072 1079
1073 // FIXME: stroking the border path causes issues with tight corners: 1080 // FIXME: stroking the border path causes issues with tight corners:
1074 // https://bugs.webkit.org/show_bug.cgi?id=58711 1081 // https://bugs.webkit.org/show_bug.cgi?id=58711
1075 graphicsContext.strokePath(centerlinePath); 1082 graphicsContext.strokePath(centerlinePath);
1076 } 1083 }
1077 1084
1078 void BoxBorderPainter::drawWideDottedBoxSideFromPath( 1085 void BoxBorderPainter::drawWideDottedBoxSideFromPath(
1079 GraphicsContext& graphicsContext, 1086 GraphicsContext& graphicsContext,
1080 const Path& borderPath, 1087 const Path& borderPath,
1081 float thickness) const { 1088 float thickness) const {
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 findIntersection(edgeQuad[2], edgeQuad[3], boundQuad1, boundQuad2, 1472 findIntersection(edgeQuad[2], edgeQuad[3], boundQuad1, boundQuad2,
1466 clippingQuad[2]); 1473 clippingQuad[2]);
1467 clippingQuad[2] -= extensionOffset; 1474 clippingQuad[2] -= extensionOffset;
1468 clippingQuad[3] = edgeQuad[3] - extensionOffset; 1475 clippingQuad[3] = edgeQuad[3] - extensionOffset;
1469 1476
1470 clipQuad(graphicsContext, clippingQuad, secondMiter == SoftMiter); 1477 clipQuad(graphicsContext, clippingQuad, secondMiter == SoftMiter);
1471 } 1478 }
1472 } 1479 }
1473 1480
1474 } // namespace blink 1481 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698