| Index: Source/core/html/canvas/CanvasRenderingContext2D.cpp
|
| diff --git a/Source/core/html/canvas/CanvasRenderingContext2D.cpp b/Source/core/html/canvas/CanvasRenderingContext2D.cpp
|
| index a0807a878501ba7dbf78ad80b7d9f2cee8a31d97..197d8497eff32c1c17d42946d56764935919a7b2 100644
|
| --- a/Source/core/html/canvas/CanvasRenderingContext2D.cpp
|
| +++ b/Source/core/html/canvas/CanvasRenderingContext2D.cpp
|
| @@ -1056,6 +1056,9 @@ void CanvasRenderingContext2D::strokeInternal(const Path& path)
|
| if (!state().m_invertibleCTM) {
|
| return;
|
| }
|
| + FloatRect clipBounds;
|
| + if (!c->getTransformedClipBounds(&clipBounds))
|
| + return;
|
|
|
| // If gradient size is zero, then paint nothing.
|
| Gradient* gradient = c->strokeGradient();
|
| @@ -1063,12 +1066,21 @@ void CanvasRenderingContext2D::strokeInternal(const Path& path)
|
| return;
|
| }
|
|
|
| - FloatRect bounds = path.boundingRect();
|
| - inflateStrokeRect(bounds);
|
| - FloatRect dirtyRect;
|
| - if (computeDirtyRect(bounds, &dirtyRect)) {
|
| + if (isFullCanvasCompositeMode(state().m_globalComposite)) {
|
| + fullCanvasCompositedStroke(path);
|
| + didDraw(clipBounds);
|
| + } else if (state().m_globalComposite == CompositeCopy) {
|
| + clearCanvas();
|
| c->strokePath(path);
|
| - didDraw(dirtyRect);
|
| + didDraw(clipBounds);
|
| + } else {
|
| + FloatRect bounds = path.boundingRect();
|
| + inflateStrokeRect(bounds);
|
| + FloatRect dirtyRect;
|
| + if (computeDirtyRect(bounds, &dirtyRect)) {
|
| + c->strokePath(path);
|
| + didDraw(dirtyRect);
|
| + }
|
| }
|
| }
|
|
|
| @@ -1345,6 +1357,9 @@ void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h
|
| return;
|
| if (!state().m_invertibleCTM)
|
| return;
|
| + FloatRect clipBounds;
|
| + if (!c->getTransformedClipBounds(&clipBounds))
|
| + return;
|
|
|
| // If gradient size is zero, then paint nothing.
|
| Gradient* gradient = c->strokeGradient();
|
| @@ -1353,12 +1368,21 @@ void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h
|
|
|
| FloatRect rect(x, y, width, height);
|
|
|
| - FloatRect boundingRect = rect;
|
| - boundingRect.inflate(state().m_lineWidth / 2);
|
| - FloatRect dirtyRect;
|
| - if (computeDirtyRect(boundingRect, &dirtyRect)) {
|
| - c->strokeRect(rect, state().m_lineWidth);
|
| - didDraw(dirtyRect);
|
| + if (isFullCanvasCompositeMode(state().m_globalComposite)) {
|
| + fullCanvasCompositedStroke(rect);
|
| + didDraw(clipBounds);
|
| + } else if (state().m_globalComposite == CompositeCopy) {
|
| + clearCanvas();
|
| + c->strokeRect(rect);
|
| + didDraw(clipBounds);
|
| + } else {
|
| + FloatRect boundingRect = rect;
|
| + boundingRect.inflate(state().m_lineWidth / 2);
|
| + FloatRect dirtyRect;
|
| + if (computeDirtyRect(boundingRect, &dirtyRect)) {
|
| + c->strokeRect(rect);
|
| + didDraw(dirtyRect);
|
| + }
|
| }
|
| }
|
|
|
| @@ -1671,6 +1695,30 @@ template<class T> void CanvasRenderingContext2D::fullCanvasCompositedFill(const
|
| c->endLayer();
|
| }
|
|
|
| +static void strokePrimitive(const FloatRect& rect, GraphicsContext* context)
|
| +{
|
| + context->strokeRect(rect);
|
| +}
|
| +
|
| +static void strokePrimitive(const Path& path, GraphicsContext* context)
|
| +{
|
| + context->strokePath(path);
|
| +}
|
| +
|
| +template<class T> void CanvasRenderingContext2D::fullCanvasCompositedStroke(const T& area)
|
| +{
|
| + ASSERT(isFullCanvasCompositeMode(state().m_globalComposite));
|
| +
|
| + GraphicsContext* c = drawingContext();
|
| + ASSERT(c);
|
| + c->beginLayer(1, state().m_globalComposite);
|
| + CompositeOperator previousOperator = c->compositeOperation();
|
| + c->setCompositeOperation(CompositeSourceOver);
|
| + strokePrimitive(area, c);
|
| + c->setCompositeOperation(previousOperator);
|
| + c->endLayer();
|
| +}
|
| +
|
| PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1, ExceptionState& exceptionState)
|
| {
|
| if (!std::isfinite(x0))
|
|
|