Changeset 191658 in webkit
- Timestamp:
- Oct 27, 2015 10:20:08 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r191652 r191658 1 2015-10-27 Hunseop Jeong <hs85.jeong@samsung.com> 2 3 [Cairo] Incorrect dashed and dotted border painting after r177686. 4 https://bugs.webkit.org/show_bug.cgi?id=141967 5 6 Reviewed by Gyuyoung Kim. 7 8 Fix the incorrect dashed/dotted border painting in cairo. 9 10 * platform/gtk/TestExpectations: Removed the passed test. 11 1 12 2015-10-27 Chris Dumez <cdumez@apple.com> 2 13 -
trunk/LayoutTests/platform/gtk/TestExpectations
r191546 r191658 530 530 webkit.org/b/141837 fast/borders/border-painting-correctness-dashed.html [ ImageOnlyFailure ] 531 531 webkit.org/b/141837 fast/borders/border-painting-correctness-dotted.html [ ImageOnlyFailure ] 532 webkit.org/b/141838 fast/borders/0px-borders.html [ ImageOnlyFailure ]533 532 534 533 webkit.org/b/141458 imported/mozilla/svg/blend-color-burn.svg [ ImageOnlyFailure ] -
trunk/Source/WebCore/ChangeLog
r191652 r191658 1 2015-10-27 Hunseop Jeong <hs85.jeong@samsung.com> 2 3 [Cairo] Incorrect dashed and dotted border painting after r177686. 4 https://bugs.webkit.org/show_bug.cgi?id=141967 5 6 Reviewed by Gyuyoung Kim. 7 8 Fix the incorrect dashed/dotted border painting in cairo. 9 10 * platform/graphics/cairo/GraphicsContextCairo.cpp: 11 (WebCore::GraphicsContext::drawLine): 12 (WebCore::calculateStrokePatternOffset): Deleted. 13 (WebCore::drawLineOnCairoContext): Deleted. 14 1 15 2015-10-27 Chris Dumez <cdumez@apple.com> 2 16 -
trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
r191617 r191658 254 254 } 255 255 256 static double calculateStrokePatternOffset(int distance, int patternWidth)257 {258 // Example: 80 pixels with a width of 30 pixels. Remainder is 20.259 // The maximum pixels of line we could paint will be 50 pixels.260 int remainder = distance % patternWidth;261 int numSegments = (distance - remainder) / patternWidth;262 263 // Special case 1px dotted borders for speed.264 if (patternWidth == 1)265 return 1;266 267 bool evenNumberOfSegments = !(numSegments % 2);268 if (remainder)269 evenNumberOfSegments = !evenNumberOfSegments;270 271 if (evenNumberOfSegments) {272 if (remainder)273 return (patternWidth - remainder) + (remainder / 2);274 return patternWidth / 2;275 }276 277 // Odd number of segments.278 if (remainder)279 return (patternWidth - remainder) / 2.f;280 return 0;281 }282 283 static void drawLineOnCairoContext(GraphicsContext* graphicsContext, cairo_t* context, const FloatPoint& point1, const FloatPoint& point2)284 {285 StrokeStyle style = graphicsContext->strokeStyle();286 if (style == NoStroke)287 return;288 289 const Color& strokeColor = graphicsContext->strokeColor();290 int strokeThickness = floorf(graphicsContext->strokeThickness());291 if (graphicsContext->strokeThickness() < 1)292 strokeThickness = 1;293 294 int patternWidth = 0;295 if (style == DottedStroke)296 patternWidth = strokeThickness;297 else if (style == DashedStroke)298 patternWidth = 3 * strokeThickness;299 300 bool isVerticalLine = point1.x() == point2.x();301 FloatPoint point1OnPixelBoundaries = point1;302 FloatPoint point2OnPixelBoundaries = point2;303 GraphicsContext::adjustLineToPixelBoundaries(point1OnPixelBoundaries, point2OnPixelBoundaries, strokeThickness, style);304 305 if (patternWidth) {306 // Do a rect fill of our endpoints. This ensures we always have the307 // appearance of being a border. We then draw the actual dotted/dashed line.308 FloatRect firstRect(point1OnPixelBoundaries, FloatSize(strokeThickness, strokeThickness));309 FloatRect secondRect(point2OnPixelBoundaries, FloatSize(strokeThickness, strokeThickness));310 if (isVerticalLine) {311 firstRect.move(-strokeThickness / 2, -strokeThickness);312 secondRect.move(-strokeThickness / 2, 0);313 } else {314 firstRect.move(-strokeThickness, -strokeThickness / 2);315 secondRect.move(0, -strokeThickness / 2);316 }317 fillRectWithColor(context, firstRect, strokeColor);318 fillRectWithColor(context, secondRect, strokeColor);319 320 int distance = (isVerticalLine ? (point2.y() - point1.y()) : (point2.x() - point1.x())) - 2 * strokeThickness;321 double patternOffset = calculateStrokePatternOffset(distance, patternWidth);322 double patternWidthAsDouble = patternWidth;323 cairo_set_dash(context, &patternWidthAsDouble, 1, patternOffset);324 }325 326 setSourceRGBAFromColor(context, strokeColor);327 cairo_set_line_width(context, strokeThickness);328 cairo_move_to(context, point1OnPixelBoundaries.x(), point1OnPixelBoundaries.y());329 cairo_line_to(context, point2OnPixelBoundaries.x(), point2OnPixelBoundaries.y());330 cairo_stroke(context);331 }332 333 256 // This is only used to draw borders, so we should not draw shadows. 334 257 void GraphicsContext::drawLine(const FloatPoint& point1, const FloatPoint& point2) … … 337 260 return; 338 261 262 if (strokeStyle() == NoStroke) 263 return; 264 265 const Color& strokeColor = this->strokeColor(); 266 float thickness = strokeThickness(); 267 bool isVerticalLine = (point1.x() + thickness == point2.x()); 268 float strokeWidth = isVerticalLine ? point2.y() - point1.y() : point2.x() - point1.x(); 269 if (!thickness || !strokeWidth) 270 return; 271 339 272 cairo_t* cairoContext = platformContext()->cr(); 340 cairo_save(cairoContext); 341 drawLineOnCairoContext(this, cairoContext, point1, point2); 342 cairo_restore(cairoContext); 273 StrokeStyle strokeStyle = this->strokeStyle(); 274 float cornerWidth = 0; 275 bool drawsDashedLine = strokeStyle == DottedStroke || strokeStyle == DashedStroke; 276 277 if (drawsDashedLine) { 278 cairo_save(cairoContext); 279 // Figure out end points to ensure we always paint corners. 280 cornerWidth = strokeStyle == DottedStroke ? thickness : std::min(2 * thickness, std::max(thickness, strokeWidth / 3)); 281 if (isVerticalLine) { 282 fillRectWithColor(cairoContext, FloatRect(point1.x(), point1.y(), thickness, cornerWidth), strokeColor); 283 fillRectWithColor(cairoContext, FloatRect(point1.x(), point2.y() - cornerWidth, thickness, cornerWidth), strokeColor); 284 } else { 285 fillRectWithColor(cairoContext, FloatRect(point1.x(), point1.y(), cornerWidth, thickness), strokeColor); 286 fillRectWithColor(cairoContext, FloatRect(point2.x() - cornerWidth, point1.y(), cornerWidth, thickness), strokeColor); 287 } 288 strokeWidth -= 2 * cornerWidth; 289 float patternWidth = strokeStyle == DottedStroke ? thickness : std::min(3 * thickness, std::max(thickness, strokeWidth / 3)); 290 // Check if corner drawing sufficiently covers the line. 291 if (strokeWidth <= patternWidth + 1) { 292 cairo_restore(cairoContext); 293 return; 294 } 295 296 // Pattern starts with full fill and ends with the empty fill. 297 // 1. Let's start with the empty phase after the corner. 298 // 2. Check if we've got odd or even number of patterns and whether they fully cover the line. 299 // 3. In case of even number of patterns and/or remainder, move the pattern start position 300 // so that the pattern is balanced between the corners. 301 float patternOffset = patternWidth; 302 int numberOfSegments = std::floor(strokeWidth / patternWidth); 303 bool oddNumberOfSegments = numberOfSegments % 2; 304 float remainder = strokeWidth - (numberOfSegments * patternWidth); 305 if (oddNumberOfSegments && remainder) 306 patternOffset -= remainder / 2.f; 307 else if (!oddNumberOfSegments) { 308 if (remainder) 309 patternOffset += patternOffset - (patternWidth + remainder) / 2.f; 310 else 311 patternOffset += patternWidth / 2.f; 312 } 313 const double dashedLine[2] = { static_cast<double>(patternWidth), static_cast<double>(patternWidth) }; 314 cairo_set_dash(cairoContext, dashedLine, 2, patternOffset); 315 } 316 317 FloatPoint p1 = point1; 318 FloatPoint p2 = point2; 319 // Center line and cut off corners for pattern patining. 320 if (isVerticalLine) { 321 float centerOffset = (p2.x() - p1.x()) / 2; 322 p1.move(centerOffset, cornerWidth); 323 p2.move(-centerOffset, -cornerWidth); 324 } else { 325 float centerOffset = (p2.y() - p1.y()) / 2; 326 p1.move(cornerWidth, centerOffset); 327 p2.move(-cornerWidth, -centerOffset); 328 } 329 330 if (shouldAntialias()) 331 cairo_set_antialias(cairoContext, CAIRO_ANTIALIAS_NONE); 332 333 cairo_new_path(cairoContext); 334 cairo_move_to(cairoContext, p1.x(), p1.y()); 335 cairo_line_to(cairoContext, p2.x(), p2.y()); 336 cairo_stroke(cairoContext); 337 if (drawsDashedLine) 338 cairo_restore(cairoContext); 339 if (shouldAntialias()) 340 cairo_set_antialias(cairoContext, CAIRO_ANTIALIAS_DEFAULT); 343 341 } 344 342
Note: See TracChangeset
for help on using the changeset viewer.