| Index: Source/core/html/canvas/CanvasRenderingContext2D.cpp
|
| diff --git a/Source/core/html/canvas/CanvasRenderingContext2D.cpp b/Source/core/html/canvas/CanvasRenderingContext2D.cpp
|
| index f1ed386879e6e11916b12d271b4693f4a3101fd4..c7b0304b5fe6892d1c23554d1566bc0d3c49c35c 100644
|
| --- a/Source/core/html/canvas/CanvasRenderingContext2D.cpp
|
| +++ b/Source/core/html/canvas/CanvasRenderingContext2D.cpp
|
| @@ -1190,15 +1190,19 @@ void CanvasRenderingContext2D::clearRect(float x, float y, float width, float he
|
| }
|
| }
|
|
|
| -// FIXME(crbug.com/425531): Funtional.h cannot handle override function signature.
|
| -static void fillRectOnContext(GraphicsContext* context, const FloatRect& rect)
|
| +static void drawRectOnCanvas(const FloatRect& rect, SkCanvas* canvas, const SkPaint* paint)
|
| {
|
| - context->fillRect(rect);
|
| -}
|
| + if (paint->getStyle() == SkPaint::kStroke_Style && ((rect.width() > 0) != (rect.height() > 0))) {
|
| + // When stroking, we must skip the zero-dimension segments
|
| + SkPath path;
|
| + path.moveTo(rect.x(), rect.y());
|
| + path.lineTo(rect.maxX(), rect.maxY());
|
| + path.close();
|
| + canvas->drawPath(path, *paint);
|
| + return;
|
| + }
|
|
|
| -static void strokeRectOnContext(GraphicsContext* context, const FloatRect& rect)
|
| -{
|
| - context->strokeRect(rect);
|
| + canvas->drawRect(rect, *paint);
|
| }
|
|
|
| void CanvasRenderingContext2D::fillRect(float x, float y, float width, float height)
|
| @@ -1206,8 +1210,7 @@ void CanvasRenderingContext2D::fillRect(float x, float y, float width, float hei
|
| if (!validateRectForCanvas(x, y, width, height))
|
| return;
|
|
|
| - GraphicsContext* c = drawingContext();
|
| - if (!c)
|
| + if (!drawingCanvas())
|
| return;
|
| if (!state().isTransformInvertible())
|
| return;
|
| @@ -1218,28 +1221,29 @@ void CanvasRenderingContext2D::fillRect(float x, float y, float width, float hei
|
| // from the HTML5 Canvas spec:
|
| // If x0 = x1 and y0 = y1, then the linear gradient must paint nothing
|
| // If x0 = x1 and y0 = y1 and r0 = r1, then the radial gradient must paint nothing
|
| - Gradient* gradient = c->fillGradient();
|
| - if (gradient && gradient->isZeroSize())
|
| + CanvasGradient* gradient = state().fillStyle()->canvasGradient();
|
| + if (gradient && gradient->gradient()->isZeroSize())
|
| return;
|
|
|
| FloatRect rect(x, y, width, height);
|
| if (rectContainsTransformedRect(rect, clipBounds)) {
|
| - checkOverdraw(rect, &c->fillPaint(), NoImage, ClipFill);
|
| - c->fillRect(rect);
|
| + const SkPaint* paint = state().getPaint(CanvasRenderingContext2DState::FillPaintType, DrawShadowAndForeground);
|
| + checkOverdraw(rect, paint, NoImage, ClipFill);
|
| + drawRectOnCanvas(rect, drawingCanvas(), paint);
|
| didDraw(clipBounds);
|
| } else if (isFullCanvasCompositeMode(state().globalComposite())) {
|
| - fullCanvasCompositedDraw(bind(&fillRectOnContext, c, rect));
|
| + fullCanvasCompositedDraw(bind<SkCanvas*, const SkPaint*>(drawRectOnCanvas, rect), CanvasRenderingContext2DState::FillPaintType, Opaque);
|
| didDraw(clipBounds);
|
| } else if (state().globalComposite() == SkXfermode::kSrc_Mode) {
|
| clearCanvas();
|
| - c->clearShadow(); // Takes care of signaling the overdraw
|
| - c->fillRect(rect);
|
| - applyShadow(DrawShadowAndForeground);
|
| + const SkPaint* paint = state().getPaint(CanvasRenderingContext2DState::FillPaintType, DrawForegroundOnly);
|
| + drawRectOnCanvas(rect, drawingCanvas(), paint);
|
| didDraw(clipBounds);
|
| } else {
|
| SkIRect dirtyRect;
|
| if (computeDirtyRect(rect, clipBounds, &dirtyRect)) {
|
| - c->fillRect(rect);
|
| + const SkPaint* paint = state().getPaint(CanvasRenderingContext2DState::FillPaintType, DrawShadowAndForeground);
|
| + drawRectOnCanvas(rect, drawingCanvas(), paint);
|
| didDraw(dirtyRect);
|
| }
|
| }
|
| @@ -1253,36 +1257,37 @@ void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h
|
| if (!(state().lineWidth() >= 0))
|
| return;
|
|
|
| - GraphicsContext* c = drawingContext();
|
| - if (!c)
|
| + if (!drawingCanvas())
|
| return;
|
| +
|
| if (!state().isTransformInvertible())
|
| return;
|
| +
|
| SkIRect clipBounds;
|
| if (!drawingCanvas()->getClipDeviceBounds(&clipBounds))
|
| return;
|
|
|
| // If gradient size is zero, then paint nothing.
|
| - Gradient* gradient = c->strokeGradient();
|
| - if (gradient && gradient->isZeroSize())
|
| + CanvasGradient* gradient = state().strokeStyle()->canvasGradient();
|
| + if (gradient && gradient->gradient()->isZeroSize())
|
| return;
|
|
|
| FloatRect rect(x, y, width, height);
|
| if (isFullCanvasCompositeMode(state().globalComposite())) {
|
| - fullCanvasCompositedDraw(bind(&strokeRectOnContext, c, rect));
|
| + fullCanvasCompositedDraw(bind<SkCanvas*, const SkPaint*>(drawRectOnCanvas, rect), CanvasRenderingContext2DState::StrokePaintType, Opaque);
|
| didDraw(clipBounds);
|
| } else if (state().globalComposite() == SkXfermode::kSrc_Mode) {
|
| clearCanvas();
|
| - c->clearShadow();
|
| - c->strokeRect(rect);
|
| - applyShadow(DrawShadowAndForeground);
|
| + const SkPaint* paint = state().getPaint(CanvasRenderingContext2DState::StrokePaintType, DrawForegroundOnly);
|
| + drawRectOnCanvas(rect, drawingCanvas(), paint);
|
| didDraw(clipBounds);
|
| } else {
|
| FloatRect boundingRect = rect;
|
| boundingRect.inflate(state().lineWidth() / 2);
|
| SkIRect dirtyRect;
|
| if (computeDirtyRect(boundingRect, clipBounds, &dirtyRect)) {
|
| - c->strokeRect(rect);
|
| + const SkPaint* paint = state().getPaint(CanvasRenderingContext2DState::StrokePaintType, DrawShadowAndForeground);
|
| + drawRectOnCanvas(rect, drawingCanvas(), paint);
|
| didDraw(dirtyRect);
|
| }
|
| }
|
| @@ -1294,7 +1299,7 @@ void CanvasRenderingContext2D::applyShadow(ShadowMode shadowMode)
|
| if (!c)
|
| return;
|
|
|
| - if (shouldDrawShadows()) {
|
| + if (state().shouldDrawShadows()) {
|
| c->setShadow(state().shadowOffset(), state().shadowBlur(), state().shadowColor(),
|
| DrawLooperBuilder::ShadowIgnoresTransforms, DrawLooperBuilder::ShadowRespectsAlpha, shadowMode);
|
| } else {
|
| @@ -1302,11 +1307,6 @@ void CanvasRenderingContext2D::applyShadow(ShadowMode shadowMode)
|
| }
|
| }
|
|
|
| -bool CanvasRenderingContext2D::shouldDrawShadows() const
|
| -{
|
| - return alphaChannel(state().shadowColor()) && (state().shadowBlur() || !state().shadowOffset().isZero());
|
| -}
|
| -
|
| static inline FloatRect normalizeRect(const FloatRect& rect)
|
| {
|
| return FloatRect(std::min(rect.x(), rect.maxX()),
|
| @@ -1499,6 +1499,32 @@ bool CanvasRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect
|
| return state().transform().mapQuad(quad).containsQuad(transformedQuad);
|
| }
|
|
|
| +void CanvasRenderingContext2D::fullCanvasCompositedDraw(PassOwnPtr<Function<void(SkCanvas*, const SkPaint*)>> draw, CanvasRenderingContext2DState::PaintType paintType, OpacityMode bitmapOpacity)
|
| +{
|
| + ASSERT(isFullCanvasCompositeMode(state().globalComposite()));
|
| + ASSERT(draw);
|
| +
|
| + SkCanvas* c = drawingCanvas();
|
| + ASSERT(c);
|
| +
|
| + SkPaint layerPaint;
|
| + layerPaint.setXfermodeMode(state().globalComposite());
|
| + if (state().shouldDrawShadows()) {
|
| + // unroll into two independently composited passes if drawing shadows
|
| + c->saveLayer(0, &layerPaint);
|
| + SkPaint shadowPaint = *state().getPaint(paintType, DrawShadowOnly, bitmapOpacity);
|
| + shadowPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
|
| + (*draw)(c, &shadowPaint);
|
| + c->restore();
|
| + }
|
| +
|
| + c->saveLayer(0, &layerPaint);
|
| + SkPaint foregroundPaint = *state().getPaint(paintType, DrawForegroundOnly, bitmapOpacity);
|
| + foregroundPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
|
| + (*draw)(c, &foregroundPaint);
|
| + c->restore();
|
| +}
|
| +
|
| void CanvasRenderingContext2D::fullCanvasCompositedDraw(PassOwnPtr<Closure> draw)
|
| {
|
| ASSERT(isFullCanvasCompositeMode(state().globalComposite()));
|
| @@ -1506,7 +1532,7 @@ void CanvasRenderingContext2D::fullCanvasCompositedDraw(PassOwnPtr<Closure> draw
|
| GraphicsContext* c = drawingContext();
|
| ASSERT(c);
|
|
|
| - if (shouldDrawShadows()) {
|
| + if (state().shouldDrawShadows()) {
|
| // unroll into two independently composited passes if drawing shadows
|
| c->beginLayer(1, state().globalComposite());
|
| c->setCompositeOperation(SkXfermode::kSrcOver_Mode);
|
| @@ -1614,7 +1640,7 @@ void CanvasRenderingContext2D::didDraw(const SkIRect& dirtyRect)
|
| if (dirtyRect.isEmpty())
|
| return;
|
|
|
| - if (ExpensiveCanvasHeuristicParameters::BlurredShadowsAreExpensive && shouldDrawShadows() && state().shadowBlur() > 0) {
|
| + if (ExpensiveCanvasHeuristicParameters::BlurredShadowsAreExpensive && state().shouldDrawShadows() && state().shadowBlur() > 0) {
|
| ImageBuffer* buffer = canvas()->buffer();
|
| if (buffer)
|
| buffer->setHasExpensiveOp();
|
|
|