Reviewed by Eric Seidel and David Levin.
Re-apply chromium/skia border fix (originally landed in r46157,
reverted in r46363), since it was not the cause of the reliability
failures in Chromium.
http://bugs.webkit.org/show_bug.cgi?id=27388
* platform/graphics/skia/GraphicsContextSkia.cpp:
(WebCore::GraphicsContext::drawLine):
* platform/graphics/skia/PlatformContextSkia.cpp:
(PlatformContextSkia::setupPaintForStroking):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@46447
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2009-07-27 Stephen White <senorblanco@chromium.org>
+
+ Reviewed by Eric Seidel and David Levin.
+
+ Re-apply chromium/skia border fix (originally landed in r46157,
+ reverted in r46363), since it was not the cause of the reliability
+ failures in Chromium.
+
+ http://bugs.webkit.org/show_bug.cgi?id=27388
+
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ (WebCore::GraphicsContext::drawLine):
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (PlatformContextSkia::setupPaintForStroking):
+
2009-07-27 Ryosuke Niwa <rniwa@webkit.org>
Reviewed by Justin Garcia.
// probably worth the speed up of no square root, which also won't be exact.
SkPoint disp = pts[1] - pts[0];
int length = SkScalarRound(disp.fX + disp.fY);
- int width = roundf(
- platformContext()->setupPaintForStroking(&paint, 0, length));
+ platformContext()->setupPaintForStroking(&paint, 0, length);
+ int width = roundf(strokeThickness());
+ bool isVerticalLine = pts[0].fX == pts[1].fX;
+
+ if (strokeStyle() == DottedStroke || strokeStyle() == DashedStroke) {
+ // Do a rect fill of our endpoints. This ensures we always have the
+ // appearance of being a border. We then draw the actual dotted/dashed line.
+
+ SkRect r1, r2;
+ r1.set(pts[0].fX, pts[0].fY, pts[0].fX + width, pts[0].fY + width);
+ r2.set(pts[1].fX, pts[1].fY, pts[1].fX + width, pts[1].fY + width);
+
+ if (isVerticalLine) {
+ r1.offset(-width / 2, 0);
+ r2.offset(-width / 2, -width);
+ } else {
+ r1.offset(0, -width / 2);
+ r2.offset(-width, -width / 2);
+ }
+ SkPaint fillPaint;
+ fillPaint.setColor(paint.getColor());
+ platformContext()->canvas()->drawRect(r1, fillPaint);
+ platformContext()->canvas()->drawRect(r2, fillPaint);
+
+ // Since we've already rendered the endcaps, adjust the endpoints to
+ // exclude them from the line itself.
+ if (isVerticalLine) {
+ pts[0].fY += width;
+ pts[1].fY -= width;
+ } else {
+ pts[0].fX += width;
+ pts[1].fX -= width;
+ }
+ }
// "Borrowed" this comment and idea from GraphicsContextCG.cpp
+ //
// For odd widths, we add in 0.5 to the appropriate x/y so that the float
// arithmetic works out. For example, with a border width of 3, KHTML will
// pass us (y1+y2)/2, e.g., (50+53)/2 = 103/2 = 51 when we want 51.5. It is
// always true that an even width gave us a perfect position, but an odd
// width gave us a position that is off by exactly 0.5.
- bool isVerticalLine = pts[0].fX == pts[1].fX;
if (width & 1) { // Odd.
if (isVerticalLine) {
width = m_state->m_dashRatio * width;
// Fall through.
case WebCore::DottedStroke:
- SkScalar dashLength;
- if (length) {
- // Determine about how many dashes or dots we should have.
- float roundedWidth = roundf(width);
- int numDashes = roundedWidth ? (length / roundedWidth) : length;
- if (!(numDashes & 1))
- numDashes++; // Make it odd so we end on a dash/dot.
- // Use the number of dashes to determine the length of a
- // dash/dot, which will be approximately width
- dashLength = SkScalarDiv(SkIntToScalar(length), SkIntToScalar(numDashes));
- } else
- dashLength = SkFloatToScalar(width);
- SkScalar intervals[2] = { dashLength, dashLength };
- paint->setPathEffect(new SkDashPathEffect(intervals, 2, 0))->unref();
+ // 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_state->m_strokeThickness);
+ 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 == 0) {
+ // Even: shift right half a dash, minus half the remainder
+ phase = (dashLength - remainder) / 2;
+ } else {
+ // Odd: shift right a full dash, minus half the remainder
+ phase = dashLength - remainder / 2;
+ }
+ }
+ SkScalar dashLengthSk = SkIntToScalar(dashLength);
+ SkScalar intervals[2] = { dashLengthSk, dashLengthSk };
+ paint->setPathEffect(new SkDashPathEffect(intervals, 2, SkIntToScalar(phase)))->unref();
}
}