| Index: third_party/WebKit/Source/platform/graphics/StrokeData.cpp
|
| diff --git a/third_party/WebKit/Source/platform/graphics/StrokeData.cpp b/third_party/WebKit/Source/platform/graphics/StrokeData.cpp
|
| index cbdb47b677f27bed5c95c4cb058e56f8c8842681..ac64a3d70ae985551a8921bfb5bb0be3f0b76dc3 100644
|
| --- a/third_party/WebKit/Source/platform/graphics/StrokeData.cpp
|
| +++ b/third_party/WebKit/Source/platform/graphics/StrokeData.cpp
|
| @@ -34,8 +34,6 @@
|
|
|
| namespace blink {
|
|
|
| -static const int dashRatio = 3; // Ratio of the length of a dash to its width.
|
| -
|
| void StrokeData::setLineDash(const DashArray& dashes, float dashOffset) {
|
| // FIXME: This is lifted directly off SkiaSupport, lines 49-74
|
| // so it is not guaranteed to work correctly.
|
| @@ -71,56 +69,46 @@ void StrokeData::setupPaintDashPathEffect(PaintFlags* flags, int length) const {
|
| if (m_dash) {
|
| flags->setPathEffect(m_dash);
|
| } else if (strokeIsDashed(m_thickness, m_style)) {
|
| - float width =
|
| - m_style == DashedStroke ? dashRatio * m_thickness : m_thickness;
|
| -
|
| - // Truncate the width, since we don't want fuzzy dots or dashes.
|
| - int dashLength = static_cast<int>(width);
|
| - // Subtract off the endcaps, since they're rendered separately.
|
| - int distance = length - 2 * static_cast<int>(m_thickness);
|
| - int phase = 1;
|
| - if (dashLength > 1) {
|
| - // Determine how many dashes or dots we should have.
|
| - int numDashes = distance / dashLength;
|
| - int remainder = distance % dashLength;
|
| - // Adjust the phase to center the dashes within the line.
|
| - if (numDashes % 2) {
|
| - // Odd: shift right a full dash, minus half the remainder.
|
| - phase = dashLength - remainder / 2;
|
| - } else {
|
| - // Even: shift right half a dash, minus half the remainder.
|
| - phase = (dashLength - remainder) / 2;
|
| - }
|
| + float dashLength = m_thickness;
|
| + float gapLength = dashLength;
|
| + if (m_style == DashedStroke) {
|
| + dashLength *= StrokeData::dashLengthRatio(m_thickness);
|
| + gapLength *= StrokeData::dashGapRatio(m_thickness);
|
| + }
|
| + // Account for modification to effective length in
|
| + // GraphicsContext::adjustLineToPixelBoundaries
|
| + length -= 2 * m_thickness;
|
| + if (length <= dashLength) {
|
| + // No space for dashes
|
| + flags->setPathEffect(0);
|
| + } else if (length <= 2 * dashLength + gapLength) {
|
| + // Exactly 2 dashes proportionally sized
|
| + float multiplier = length / (2 * dashLength + gapLength);
|
| + SkScalar intervals[2] = {dashLength * multiplier, gapLength * multiplier};
|
| + flags->setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
|
| + } else {
|
| + float gap = gapLength;
|
| + if (m_style == DashedStroke)
|
| + gap = selectBestDashGap(length, dashLength, gapLength);
|
| + SkScalar intervals[2] = {dashLength, gap};
|
| + flags->setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
|
| }
|
| - SkScalar dashLengthSk = SkIntToScalar(dashLength);
|
| - SkScalar intervals[2] = {dashLengthSk, dashLengthSk};
|
| - flags->setPathEffect(
|
| - SkDashPathEffect::Make(intervals, 2, SkIntToScalar(phase)));
|
| } else if (m_style == DottedStroke) {
|
| flags->setStrokeCap((PaintFlags::Cap)RoundCap);
|
| // Adjust the width to get equal dot spacing as much as possible.
|
| float perDotLength = m_thickness * 2;
|
| - static float epsilon = 1.0e-2f;
|
| - if (length < perDotLength + m_thickness) {
|
| - // Exactly 2 dots with whatever space we can get
|
| - SkScalar intervals[2] = {0, length - m_thickness - epsilon};
|
| + if (length < perDotLength) {
|
| + // Not enoguh space for 2 dots. Just draw 1 by giving a gap that is
|
| + // bigger than the length.
|
| + SkScalar intervals[2] = {0, perDotLength};
|
| flags->setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
|
| return;
|
| }
|
|
|
| - // Determine what number of dots gives the minimum deviation from
|
| - // idealGap between dots. Set the gap to that width.
|
| - float minNumDots = floorf((length + m_thickness) / perDotLength);
|
| - float maxNumDots = minNumDots + 1;
|
| - float minGap = (length - minNumDots * m_thickness) / (minNumDots - 1);
|
| - float maxGap = (length - maxNumDots * m_thickness) / (maxNumDots - 1);
|
| - if (fabs(minGap - m_thickness) < fabs(maxGap - m_thickness)) {
|
| - SkScalar intervals[2] = {0, minGap + m_thickness - epsilon};
|
| - flags->setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
|
| - } else {
|
| - SkScalar intervals[2] = {0, maxGap + m_thickness - epsilon};
|
| - flags->setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
|
| - }
|
| + static const float epsilon = 1.0e-2f;
|
| + float gap = selectBestDashGap(length, m_thickness, m_thickness);
|
| + SkScalar intervals[2] = {0, gap + m_thickness - epsilon};
|
| + flags->setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
|
| } else {
|
| // TODO(schenney): WavyStroke https://crbug.com/229574
|
| flags->setPathEffect(0);
|
| @@ -131,4 +119,19 @@ bool StrokeData::strokeIsDashed(float width, StrokeStyle style) {
|
| return style == DashedStroke || (style == DottedStroke && width <= 3);
|
| }
|
|
|
| +float StrokeData::selectBestDashGap(float strokeLength,
|
| + float dashLength,
|
| + float gapLength) {
|
| + // Determine what number of dashes gives the minimum deviation from
|
| + // gapLength between dashes. Set the gap to that width.
|
| + float minNumDashes =
|
| + floorf((strokeLength + gapLength) / (dashLength + gapLength));
|
| + float maxNumDashes = minNumDashes + 1;
|
| + float minGap =
|
| + (strokeLength - minNumDashes * dashLength) / (minNumDashes - 1);
|
| + float maxGap =
|
| + (strokeLength - maxNumDashes * dashLength) / (maxNumDashes - 1);
|
| + return fabs(minGap - gapLength) < fabs(maxGap - gapLength) ? minGap : maxGap;
|
| +}
|
| +
|
| } // namespace blink
|
|
|