Changeset 21601 in webkit
- Timestamp:
- May 19, 2007 3:54:26 PM (17 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r21600 r21601 1 2007-05-19 Mitz Pettel <mitz@webkit.org> 2 3 Reviewed by Darin. 4 5 - http://bugs.webkit.org/show_bug.cgi?id=13320 6 rounded corners with drop shadows are really slow 7 8 * fast/box-shadow/border-radius-big-expected.checksum: Added. 9 * fast/box-shadow/border-radius-big-expected.png: Added. 10 * fast/box-shadow/border-radius-big-expected.txt: Added. 11 * fast/box-shadow/border-radius-big.html: Added. 12 1 13 2007-05-19 Anders Carlsson <andersca@apple.com> 2 14 -
trunk/WebCore/ChangeLog
r21600 r21601 1 2007-05-19 Mitz Pettel <mitz@webkit.org> 2 3 Reviewed by Darin. 4 5 - http://bugs.webkit.org/show_bug.cgi?id=13320 6 rounded corners with drop shadows are really slow 7 8 Test for a rendering bug fixed by this patch: 9 fast/box-shadow/border-radius-big.html 10 11 No test for the performance ingredient. 12 13 * platform/graphics/GraphicsContext.cpp: 14 (WebCore::GraphicsContext::addRoundedRectClip): Made cross-platform. 15 Changed to use a single clipping path. If all the radii cannot be 16 accommodated, clips to a rect. 17 (WebCore::GraphicsContext::clipOutRoundedRect): Changed to use a single 18 clipping path. If all the radii cannot be accommodated, clips out a rect. 19 * platform/graphics/GraphicsContext.h: Added clipOut(const Path&). 20 * platform/graphics/Path.cpp: 21 (WebCore::Path::createRoundedRectangle): Added. Returns a rounded rectangle 22 with the specified radii. If all the radii cannot be accommodated, returns 23 a rectangular path. 24 * platform/graphics/Path.h: 25 * platform/graphics/cairo/GraphicsContextCairo.cpp: 26 (WebCore::GraphicsContext::clipOut): Added. 27 * platform/graphics/cg/GraphicsContextCG.cpp: 28 (WebCore::GraphicsContext::fillRoundedRect): Changed to use a single path. 29 (WebCore::GraphicsContext::clipOut): Added. 30 * platform/graphics/qt/GraphicsContextQt.cpp: 31 (WebCore::GraphicsContext::clipOut): Added. 32 1 33 2007-05-19 Anders Carlsson <andersca@apple.com> 2 34 -
trunk/WebCore/platform/graphics/GraphicsContext.cpp
r20646 r21601 316 316 } 317 317 318 void GraphicsContext::addRoundedRectClip(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, 319 const IntSize& bottomLeft, const IntSize& bottomRight) 320 { 321 if (paintingDisabled()) 322 return; 323 324 clip(Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight)); 325 } 326 318 327 void GraphicsContext::clipOutRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, 319 328 const IntSize& bottomLeft, const IntSize& bottomRight) … … 321 330 if (paintingDisabled()) 322 331 return; 323 324 // Need sufficient width and height to contain these curves. Sanity check our 325 // corner radii and our width/height values to make sure the curves can all fit. 326 if (static_cast<unsigned>(rect.width()) < static_cast<unsigned>(topLeft.width()) + static_cast<unsigned>(topRight.width()) || 327 static_cast<unsigned>(rect.width()) < static_cast<unsigned>(bottomLeft.width()) + static_cast<unsigned>(bottomRight.width()) || 328 static_cast<unsigned>(rect.height()) < static_cast<unsigned>(topLeft.height()) + static_cast<unsigned>(bottomLeft.height()) || 329 static_cast<unsigned>(rect.height()) < static_cast<unsigned>(topRight.height()) + static_cast<unsigned>(bottomRight.height())) 330 return; 331 332 // Clip out each shape one by one. 333 clipOutEllipseInRect(IntRect(rect.x(), rect.y(), topLeft.width() * 2, topLeft.height() * 2)); 334 clipOutEllipseInRect(IntRect(rect.right() - topRight.width() * 2, rect.y(), topRight.width() * 2, topRight.height() * 2)); 335 clipOutEllipseInRect(IntRect(rect.x(), rect.bottom() - bottomLeft.height() * 2, bottomLeft.width() * 2, bottomLeft.height() * 2)); 336 clipOutEllipseInRect(IntRect(rect.right() - bottomRight.width() * 2, rect.bottom() - bottomRight.height() * 2, bottomRight.width() * 2, bottomRight.height() * 2)); 337 clipOut(IntRect(rect.x() + topLeft.width(), rect.y(), 338 rect.width() - topLeft.width() - topRight.width(), 339 max(topLeft.height(), topRight.height()))); 340 clipOut(IntRect(rect.x() + bottomLeft.width(), 341 rect.bottom() - max(bottomLeft.height(), bottomRight.height()), 342 rect.width() - bottomLeft.width() - bottomRight.width(), 343 max(bottomLeft.height(), bottomRight.height()))); 344 clipOut(IntRect(rect.x(), rect.y() + topLeft.height(), 345 max(topLeft.width(), bottomLeft.width()), rect.height() - topLeft.height() - bottomLeft.height())); 346 clipOut(IntRect(rect.right() - max(topRight.width(), bottomRight.width()), 347 rect.y() + topRight.height(), 348 max(topRight.width(), bottomRight.width()), rect.height() - topRight.height() - bottomRight.height())); 349 clipOut(IntRect(rect.x() + max(topLeft.width(), bottomLeft.width()), 350 rect.y() + max(topLeft.height(), topRight.height()), 351 rect.width() - max(topLeft.width(), bottomLeft.width()) - max(topRight.width(), bottomRight.width()), 352 rect.height() - max(topLeft.height(), topRight.height()) - max(bottomLeft.height(), bottomRight.height()))); 332 333 clipOut(Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight)); 353 334 } 354 335 -
trunk/WebCore/platform/graphics/GraphicsContext.h
r20646 r21601 178 178 179 179 void beginPath(); 180 void addPath(const Path& path);180 void addPath(const Path&); 181 181 182 182 void clip(const Path&); 183 void clipOut(const Path&); 183 184 184 185 void scale(const FloatSize&); -
trunk/WebCore/platform/graphics/Path.cpp
r19970 r21601 159 159 } 160 160 161 Path Path::createRoundedRectangle(const FloatRect& rectangle, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius) 162 { 163 Path path; 164 165 float width = rectangle.width(); 166 float height = rectangle.height(); 167 if (width <= 0.0 || height <= 0.0) 168 return path; 169 170 if (width < topLeftRadius.width() + topRightRadius.width() 171 || width < bottomLeftRadius.width() + bottomRightRadius.width() 172 || height < topLeftRadius.height() + bottomLeftRadius.height() 173 || height < topRightRadius.height() + bottomRightRadius.height()) 174 // If all the radii cannot be accommodated, return a rect. 175 return createRectangle(rectangle); 176 177 float x = rectangle.x(); 178 float y = rectangle.y(); 179 180 path.moveTo(FloatPoint(x + topLeftRadius.width(), y)); 181 182 path.addLineTo(FloatPoint(x + width - topRightRadius.width(), y)); 183 184 path.addBezierCurveTo(FloatPoint(x + width - topRightRadius.width() * (1 - QUARTER), y), FloatPoint(x + width, y + topRightRadius.height() * (1 - QUARTER)), FloatPoint(x + width, y + topRightRadius.height())); 185 186 path.addLineTo(FloatPoint(x + width, y + height - bottomRightRadius.height())); 187 188 path.addBezierCurveTo(FloatPoint(x + width, y + height - bottomRightRadius.height() * (1 - QUARTER)), FloatPoint(x + width - bottomRightRadius.width() * (1 - QUARTER), y + height), FloatPoint(x + width - bottomRightRadius.width(), y + height)); 189 190 path.addLineTo(FloatPoint(x + bottomLeftRadius.width(), y + height)); 191 192 path.addBezierCurveTo(FloatPoint(x + bottomLeftRadius.width() * (1 - QUARTER), y + height), FloatPoint(x, y + height - bottomLeftRadius.height() * (1 - QUARTER)), FloatPoint(x, y + height - bottomLeftRadius.height())); 193 194 path.addLineTo(FloatPoint(x, y + topLeftRadius.height())); 195 196 path.addBezierCurveTo(FloatPoint(x, y + topLeftRadius.height() * (1 - QUARTER)), FloatPoint(x + topLeftRadius.width() * (1 - QUARTER), y), FloatPoint(x + topLeftRadius.width(), y)); 197 198 path.closeSubpath(); 199 200 return path; 201 } 202 161 203 Path Path::createRectangle(const FloatRect& rectangle) 162 204 { -
trunk/WebCore/platform/graphics/Path.h
r18518 r21601 104 104 105 105 static Path createRoundedRectangle(const FloatRect&, const FloatSize& roundingRadii); 106 static Path createRoundedRectangle(const FloatRect&, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius); 106 107 static Path createRectangle(const FloatRect&); 107 108 static Path createEllipse(const FloatPoint& center, float rx, float ry); -
trunk/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
r21134 r21601 547 547 { 548 548 notImplemented(); 549 }550 551 void GraphicsContext::addRoundedRectClip(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight,552 const IntSize& bottomLeft, const IntSize& bottomRight)553 {554 notImplemented();555 549 } 556 550 … … 704 698 } 705 699 700 void GraphicsContext::clipOut(const Path&) 701 { 702 notImplemented(); 703 } 704 706 705 void GraphicsContext::rotate(float angle) 707 706 { -
trunk/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
r21074 r21601 437 437 setCGFillColor(context, color); 438 438 439 // Add the four ellipses to the path. Technically this really isn't good enough, since we could end up 440 // not clipping the other 3/4 of the ellipse we don't care about. We're relying on the fact that for 441 // normal use cases these ellipses won't overlap one another (or when they do the curvature of one will 442 // be subsumed by the other). 443 CGContextAddEllipseInRect(context, CGRectMake(rect.x(), rect.y(), topLeft.width() * 2, topLeft.height() * 2)); 444 CGContextAddEllipseInRect(context, CGRectMake(rect.right() - topRight.width() * 2, rect.y(), 445 topRight.width() * 2, topRight.height() * 2)); 446 CGContextAddEllipseInRect(context, CGRectMake(rect.x(), rect.bottom() - bottomLeft.height() * 2, 447 bottomLeft.width() * 2, bottomLeft.height() * 2)); 448 CGContextAddEllipseInRect(context, CGRectMake(rect.right() - bottomRight.width() * 2, 449 rect.bottom() - bottomRight.height() * 2, 450 bottomRight.width() * 2, bottomRight.height() * 2)); 451 452 // Now add five rects (one for each edge rect in between the rounded corners and one for the interior). 453 CGContextAddRect(context, CGRectMake(rect.x() + topLeft.width(), rect.y(), 454 rect.width() - topLeft.width() - topRight.width(), 455 max(topLeft.height(), topRight.height()))); 456 CGContextAddRect(context, CGRectMake(rect.x() + bottomLeft.width(), 457 rect.bottom() - max(bottomLeft.height(), bottomRight.height()), 458 rect.width() - bottomLeft.width() - bottomRight.width(), 459 max(bottomLeft.height(), bottomRight.height()))); 460 CGContextAddRect(context, CGRectMake(rect.x(), rect.y() + topLeft.height(), 461 max(topLeft.width(), bottomLeft.width()), rect.height() - topLeft.height() - bottomLeft.height())); 462 CGContextAddRect(context, CGRectMake(rect.right() - max(topRight.width(), bottomRight.width()), 463 rect.y() + topRight.height(), 464 max(topRight.width(), bottomRight.width()), rect.height() - topRight.height() - bottomRight.height())); 465 CGContextAddRect(context, CGRectMake(rect.x() + max(topLeft.width(), bottomLeft.width()), 466 rect.y() + max(topLeft.height(), topRight.height()), 467 rect.width() - max(topLeft.width(), bottomLeft.width()) - max(topRight.width(), bottomRight.width()), 468 rect.height() - max(topLeft.height(), topRight.height()) - max(bottomLeft.height(), bottomRight.height()))); 439 addPath(Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight)); 469 440 CGContextFillPath(context); 441 470 442 if (oldFillColor != color) 471 443 setCGFillColor(context, oldFillColor); … … 501 473 CGContextAddEllipseInRect(platformContext(), rect); 502 474 CGContextEOClip(platformContext()); 503 }504 505 void GraphicsContext::addRoundedRectClip(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight,506 const IntSize& bottomLeft, const IntSize& bottomRight)507 {508 if (paintingDisabled())509 return;510 511 // Need sufficient width and height to contain these curves. Sanity check our512 // corner radii and our width/height values to make sure the curves can all fit.513 if (static_cast<unsigned>(rect.width()) < static_cast<unsigned>(topLeft.width()) + static_cast<unsigned>(topRight.width()) ||514 static_cast<unsigned>(rect.width()) < static_cast<unsigned>(bottomLeft.width()) + static_cast<unsigned>(bottomRight.width()) ||515 static_cast<unsigned>(rect.height()) < static_cast<unsigned>(topLeft.height()) + static_cast<unsigned>(bottomLeft.height()) ||516 static_cast<unsigned>(rect.height()) < static_cast<unsigned>(topRight.height()) + static_cast<unsigned>(bottomRight.height()))517 return;518 519 // Clip to our rect.520 clip(rect);521 522 // OK, the curves can fit.523 CGContextRef context = platformContext();524 525 // Add the four ellipses to the path. Technically this really isn't good enough, since we could end up526 // not clipping the other 3/4 of the ellipse we don't care about. We're relying on the fact that for527 // normal use cases these ellipses won't overlap one another (or when they do the curvature of one will528 // be subsumed by the other).529 CGContextAddEllipseInRect(context, CGRectMake(rect.x(), rect.y(), topLeft.width() * 2, topLeft.height() * 2));530 CGContextAddEllipseInRect(context, CGRectMake(rect.right() - topRight.width() * 2, rect.y(),531 topRight.width() * 2, topRight.height() * 2));532 CGContextAddEllipseInRect(context, CGRectMake(rect.x(), rect.bottom() - bottomLeft.height() * 2,533 bottomLeft.width() * 2, bottomLeft.height() * 2));534 CGContextAddEllipseInRect(context, CGRectMake(rect.right() - bottomRight.width() * 2,535 rect.bottom() - bottomRight.height() * 2,536 bottomRight.width() * 2, bottomRight.height() * 2));537 538 // Now add five rects (one for each edge rect in between the rounded corners and one for the interior).539 CGContextAddRect(context, CGRectMake(rect.x() + topLeft.width(), rect.y(),540 rect.width() - topLeft.width() - topRight.width(),541 max(topLeft.height(), topRight.height())));542 CGContextAddRect(context, CGRectMake(rect.x() + bottomLeft.width(),543 rect.bottom() - max(bottomLeft.height(), bottomRight.height()),544 rect.width() - bottomLeft.width() - bottomRight.width(),545 max(bottomLeft.height(), bottomRight.height())));546 CGContextAddRect(context, CGRectMake(rect.x(), rect.y() + topLeft.height(),547 max(topLeft.width(), bottomLeft.width()), rect.height() - topLeft.height() - bottomLeft.height()));548 CGContextAddRect(context, CGRectMake(rect.right() - max(topRight.width(), bottomRight.width()),549 rect.y() + topRight.height(),550 max(topRight.width(), bottomRight.width()), rect.height() - topRight.height() - bottomRight.height()));551 CGContextAddRect(context, CGRectMake(rect.x() + max(topLeft.width(), bottomLeft.width()),552 rect.y() + max(topLeft.height(), topRight.height()),553 rect.width() - max(topLeft.width(), bottomLeft.width()) - max(topRight.width(), bottomRight.width()),554 rect.height() - max(topLeft.height(), topRight.height()) - max(bottomLeft.height(), bottomRight.height())));555 CGContextClip(context);556 475 } 557 476 … … 704 623 CGContextClip(context); 705 624 m_data->clip(path); 625 } 626 627 void GraphicsContext::clipOut(const Path& path) 628 { 629 if (paintingDisabled()) 630 return; 631 632 CGContextBeginPath(platformContext()); 633 CGContextAddRect(platformContext(), CGContextGetClipBoundingBox(platformContext())); 634 CGContextAddPath(platformContext(), path.platformPath()); 635 CGContextEOClip(platformContext()); 706 636 } 707 637 -
trunk/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
r21554 r21601 724 724 } 725 725 726 void GraphicsContext::clipOut(const Path& path) 727 { 728 if (paintingDisabled()) 729 return; 730 731 // FIXME: Implement 732 notImplemented(); 733 } 734 726 735 void GraphicsContext::translate(float x, float y) 727 736 { … … 794 803 } 795 804 796 void GraphicsContext::addRoundedRectClip(const IntRect& rect, const IntSize& topLeft,797 const IntSize& topRight, const IntSize& bottomLeft,798 const IntSize& bottomRight)799 {800 if (paintingDisabled())801 return;802 803 // Need sufficient width and height to contain these curves. Sanity check our top/bottom804 // values and our width/height values to make sure the curves can all fit.805 int requiredWidth = qMax(topLeft.width() + topRight.width(), bottomLeft.width() + bottomRight.width());806 if (requiredWidth > rect.width())807 return;808 809 int requiredHeight = qMax(topLeft.height() + bottomLeft.height(), topRight.height() + bottomRight.height());810 if (requiredHeight > rect.height())811 return;812 813 // Clip to our rect.814 clip(rect);815 816 // OK, the curves can fit.817 QPainterPath path;818 819 // Add the four ellipses to the path. Technically this really isn't good enough, since we could end up820 // not clipping the other 3/4 of the ellipse we don't care about. We're relying on the fact that for821 // normal use cases these ellipses won't overlap one another (or when they do the curvature of one will822 // be subsumed by the other).823 path.addEllipse(QRectF(rect.x(), rect.y(), topLeft.width() * 2, topLeft.height() * 2));824 path.addEllipse(QRectF(rect.right() - topRight.width() * 2, rect.y(),825 topRight.width() * 2, topRight.height() * 2));826 path.addEllipse(QRectF(rect.x(), rect.bottom() - bottomLeft.height() * 2,827 bottomLeft.width() * 2, bottomLeft.height() * 2));828 path.addEllipse(QRectF(rect.right() - bottomRight.width() * 2,829 rect.bottom() - bottomRight.height() * 2,830 bottomRight.width() * 2, bottomRight.height() * 2));831 832 int topLeftRightHeightMax = qMax(topLeft.height(), topRight.height());833 int bottomLeftRightHeightMax = qMax(bottomLeft.height(), bottomRight.height());834 835 int topBottomLeftWidthMax = qMax(topLeft.width(), bottomLeft.width());836 int topBottomRightWidthMax = qMax(topRight.width(), bottomRight.width());837 838 // Now add five rects (one for each edge rect in between the rounded corners and one for the interior).839 path.addRect(QRectF(rect.x() + topLeft.width(),840 rect.y(),841 rect.width() - topLeft.width() - topRight.width(),842 topLeftRightHeightMax));843 844 path.addRect(QRectF(rect.x() + bottomLeft.width(), rect.bottom() - bottomLeftRightHeightMax,845 rect.width() - bottomLeft.width() - bottomRight.width(), bottomLeftRightHeightMax));846 847 path.addRect(QRectF(rect.x(),848 rect.y() + topLeft.height(),849 topBottomLeftWidthMax,850 rect.height() - topLeft.height() - bottomLeft.height()));851 852 path.addRect(QRectF(rect.right() - topBottomRightWidthMax,853 rect.y() + topRight.height(),854 topBottomRightWidthMax,855 rect.height() - topRight.height() - bottomRight.height()));856 857 path.addRect(QRectF(rect.x() + topBottomLeftWidthMax,858 rect.y() + topLeftRightHeightMax,859 rect.width() - topBottomLeftWidthMax - topBottomRightWidthMax,860 rect.height() - topLeftRightHeightMax - bottomLeftRightHeightMax));861 862 path.setFillRule(Qt::WindingFill);863 m_data->p().setClipPath(path, Qt::IntersectClip);864 }865 866 805 void GraphicsContext::concatCTM(const AffineTransform& transform) 867 806 {
Note: See TracChangeset
for help on using the changeset viewer.