Chromium Code Reviews| Index: Source/core/html/canvas/CanvasRenderingContext2D.cpp |
| diff --git a/Source/core/html/canvas/CanvasRenderingContext2D.cpp b/Source/core/html/canvas/CanvasRenderingContext2D.cpp |
| index 0c2a7012560dde716082fe8241e87224dd7b78a7..48dca65e7ce2b3cb30e323e290ccaa9ec6280907 100644 |
| --- a/Source/core/html/canvas/CanvasRenderingContext2D.cpp |
| +++ b/Source/core/html/canvas/CanvasRenderingContext2D.cpp |
| @@ -1191,14 +1191,9 @@ void CanvasRenderingContext2D::clearRect(float x, float y, float width, float he |
| } |
| // FIXME(crbug.com/425531): Funtional.h cannot handle override function signature. |
|
Stephen White
2015/03/18 22:09:34
Is this comment still relevant?
Justin Novosad
2015/03/19 14:32:21
Yes, unfortunately. because drawRect is virtual, w
|
| -static void fillRectOnContext(GraphicsContext* context, const FloatRect& rect) |
| +static void drawRectOnCanvas(const FloatRect& rect, SkCanvas* canvas, const SkPaint* paint) |
| { |
| - context->fillRect(rect); |
| -} |
| - |
| -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 +1201,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 +1212,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().skPaint(FillPaintType, DrawShadowAndForeground, DrawLooperShadowStrategy); |
| + checkOverdraw(rect, paint, NoImage, ClipFill); |
| + drawingCanvas()->drawRect(rect, *paint); |
| didDraw(clipBounds); |
| } else if (isFullCanvasCompositeMode(state().globalComposite())) { |
| - fullCanvasCompositedDraw(bind(&fillRectOnContext, c, rect)); |
| + fullCanvasCompositedDraw(bind<SkCanvas*, const SkPaint*>(drawRectOnCanvas, rect), FillPaintType, DrawLooperShadowStrategy); |
| 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().skPaint(FillPaintType, DrawForegroundOnly, DrawLooperShadowStrategy); |
| + drawingCanvas()->drawRect(rect, *paint); |
| didDraw(clipBounds); |
| } else { |
| SkIRect dirtyRect; |
| if (computeDirtyRect(rect, clipBounds, &dirtyRect)) { |
| - c->fillRect(rect); |
| + const SkPaint* paint = state().skPaint(FillPaintType, DrawShadowAndForeground, DrawLooperShadowStrategy); |
| + drawingCanvas()->drawRect(rect, *paint); |
| didDraw(dirtyRect); |
| } |
| } |
| @@ -1253,36 +1248,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), StrokePaintType, DrawLooperShadowStrategy); |
| didDraw(clipBounds); |
| } else if (state().globalComposite() == SkXfermode::kSrc_Mode) { |
| clearCanvas(); |
| - c->clearShadow(); |
| - c->strokeRect(rect); |
| - applyShadow(DrawShadowAndForeground); |
| + const SkPaint* paint = state().skPaint(StrokePaintType, DrawForegroundOnly, DrawLooperShadowStrategy); |
| + drawingCanvas()->drawRect(rect, *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().skPaint(StrokePaintType, DrawShadowAndForeground, DrawLooperShadowStrategy); |
| + drawingCanvas()->drawRect(rect, *paint); |
| didDraw(dirtyRect); |
| } |
| } |
| @@ -1294,7 +1290,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 +1298,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 +1490,32 @@ bool CanvasRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect |
| return state().transform().mapQuad(quad).containsQuad(transformedQuad); |
| } |
| +void CanvasRenderingContext2D::fullCanvasCompositedDraw(PassOwnPtr<Function<void(SkCanvas*, const SkPaint*)>> draw, CanvasPaintType paintType, CanvasShadowStrategy shadowStrategy) |
| +{ |
| + 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().skPaint(paintType, DrawShadowOnly, shadowStrategy); |
| + shadowPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode); |
| + (*draw)(c, &shadowPaint); |
| + c->restore(); |
| + } |
| + |
| + c->saveLayer(0, &layerPaint); |
| + SkPaint foregroundPaint = *state().skPaint(paintType, DrawForegroundOnly, shadowStrategy); |
| + foregroundPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode); |
| + (*draw)(c, &foregroundPaint); |
| + c->restore(); |
| +} |
| + |
| void CanvasRenderingContext2D::fullCanvasCompositedDraw(PassOwnPtr<Closure> draw) |
| { |
| ASSERT(isFullCanvasCompositeMode(state().globalComposite())); |
| @@ -1506,7 +1523,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 +1631,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(); |