Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1152)

Unified Diff: Source/core/html/canvas/CanvasRenderingContext2D.cpp

Issue 1008173003: Move SkPaint mangement for 2D canvas into CanvasRenderingContext2DState (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: applied review comments Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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();
« no previous file with comments | « Source/core/html/canvas/CanvasRenderingContext2D.h ('k') | Source/core/html/canvas/CanvasRenderingContext2DState.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698