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(); |