| Index: third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp
|
| diff --git a/third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp b/third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp
|
| index 8d10bb36913b631082af996af9c3d0ff7a1bdb97..3308fa3809bd15a074be97eac0de8d8b02d0fcc2 100644
|
| --- a/third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp
|
| +++ b/third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp
|
| @@ -976,7 +976,7 @@ void BoxBorderPainter::drawBoxSideFromPath(GraphicsContext& graphicsContext,
|
| return;
|
| case BorderStyleDotted:
|
| case BorderStyleDashed: {
|
| - drawDashedDottedBoxSideFromPath(graphicsContext, borderPath, thickness,
|
| + drawDashedDottedBoxSideFromPath(graphicsContext, borderRect, thickness,
|
| drawThickness, color, borderStyle);
|
| return;
|
| }
|
| @@ -1011,18 +1011,34 @@ void BoxBorderPainter::drawBoxSideFromPath(GraphicsContext& graphicsContext,
|
|
|
| void BoxBorderPainter::drawDashedDottedBoxSideFromPath(
|
| GraphicsContext& graphicsContext,
|
| - const Path& borderPath,
|
| + const LayoutRect& borderRect,
|
| float thickness,
|
| float drawThickness,
|
| Color color,
|
| EBorderStyle borderStyle) const {
|
| + // Convert the path to be down the middle of the dots or dashes.
|
| + const LayoutRectOutsets centerOffsets(
|
| + -m_edges[BSTop].usedWidth() * 0.5, -m_edges[BSRight].usedWidth() * 0.5,
|
| + -m_edges[BSBottom].usedWidth() * 0.5, -m_edges[BSLeft].usedWidth() * 0.5);
|
| + Path centerlinePath;
|
| + centerlinePath.addRoundedRect(m_style.getRoundedInnerBorderFor(
|
| + borderRect, centerOffsets, m_includeLogicalLeftEdge,
|
| + m_includeLogicalRightEdge));
|
| +
|
| graphicsContext.setStrokeColor(color);
|
|
|
| + if (!StrokeData::strokeIsDashed(thickness, borderStyle == BorderStyleDashed
|
| + ? DashedStroke
|
| + : DottedStroke)) {
|
| + drawWideDottedBoxSideFromPath(graphicsContext, centerlinePath, thickness);
|
| + return;
|
| + }
|
| +
|
| // The stroke is doubled here because the provided path is the
|
| // outside edge of the border so half the stroke is clipped off.
|
| // The extra multiplier is so that the clipping mask can antialias
|
| // the edges to prevent jaggies.
|
| - graphicsContext.setStrokeThickness(drawThickness * 2 * 1.1f);
|
| + graphicsContext.setStrokeThickness(drawThickness * 1.1f);
|
| graphicsContext.setStrokeStyle(
|
| borderStyle == BorderStyleDashed ? DashedStroke : DottedStroke);
|
|
|
| @@ -1034,11 +1050,10 @@ void BoxBorderPainter::drawDashedDottedBoxSideFromPath(
|
| // do the same thing as StrokeData::setupPaintDashPathEffect and should be
|
| // refactored to re-use that code. It would require
|
| // GraphicsContext::strokePath to take a length parameter.
|
| -
|
| float dashLength =
|
| thickness * ((borderStyle == BorderStyleDashed) ? 3.0f : 1.0f);
|
| float gapLength = dashLength;
|
| - float numberOfDashes = borderPath.length() / dashLength;
|
| + float numberOfDashes = centerlinePath.length() / dashLength;
|
| // Don't try to show dashes if we have less than 2 dashes + 2 gaps.
|
| // FIXME: should do this test per side.
|
| if (numberOfDashes >= 4) {
|
| @@ -1057,8 +1072,50 @@ void BoxBorderPainter::drawDashedDottedBoxSideFromPath(
|
|
|
| // FIXME: stroking the border path causes issues with tight corners:
|
| // https://bugs.webkit.org/show_bug.cgi?id=58711
|
| - // Also, to get the best appearance we should stroke a path between the
|
| - // two borders.
|
| + graphicsContext.strokePath(centerlinePath);
|
| +}
|
| +
|
| +void BoxBorderPainter::drawWideDottedBoxSideFromPath(
|
| + GraphicsContext& graphicsContext,
|
| + const Path& borderPath,
|
| + float thickness) const {
|
| + graphicsContext.setStrokeThickness(thickness);
|
| + graphicsContext.setStrokeStyle(DottedStroke);
|
| +
|
| + // TODO(schenney): This code for setting up the dash effect is largely
|
| + // duplicated from StrokeData::setupPaintDashPathEffect and both this code
|
| + // and the method above should be refactored to re-use that code. It would
|
| + // require GraphicsContext::strokePath to take a length parameter.
|
| + graphicsContext.setLineCap(RoundCap);
|
| +
|
| + // Adjust the width to get equal dot spacing as much as possible.
|
| + float perDotLength = thickness * 2;
|
| + static float epsilon = 1.0e-2f;
|
| + float pathLength = borderPath.length();
|
| +
|
| + if (pathLength < perDotLength + thickness) {
|
| + // Exactly 2 dots with whatever space we can get
|
| + DashArray lineDash;
|
| + lineDash.push_back(0);
|
| + lineDash.push_back(pathLength - thickness - epsilon);
|
| + graphicsContext.setLineDash(lineDash, 0);
|
| + } else {
|
| + // Determine what number of dots gives the minimum deviation from
|
| + // idealGap between dots. Set the gap to that width.
|
| + float minNumDots = floorf((pathLength + thickness) / perDotLength);
|
| + float maxNumDots = minNumDots + 1;
|
| + float minGap = (pathLength - minNumDots * thickness) / (minNumDots - 1);
|
| + float maxGap = (pathLength - maxNumDots * thickness) / (maxNumDots - 1);
|
| + auto gap =
|
| + fabs(minGap - thickness) < fabs(maxGap - thickness) ? minGap : maxGap;
|
| + DashArray lineDash;
|
| + lineDash.push_back(0);
|
| + lineDash.push_back(gap + thickness - epsilon);
|
| + graphicsContext.setLineDash(lineDash, 0);
|
| + }
|
| +
|
| + // TODO(schenney): stroking the border path causes issues with tight corners:
|
| + // https://bugs.webkit.org/show_bug.cgi?id=58711
|
| graphicsContext.strokePath(borderPath);
|
| }
|
|
|
|
|