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

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

Issue 1194733002: Adding the 'filter' context attribute to 2D canvas (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: applied corrections Created 5 years, 6 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 ad626b2ac61dbe69366729cc585de45edfb25b38..530881d4f49bea62f88371beefff705ace8d1576 100644
--- a/Source/core/html/canvas/CanvasRenderingContext2D.cpp
+++ b/Source/core/html/canvas/CanvasRenderingContext2D.cpp
@@ -645,6 +645,25 @@ void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operati
modifiableState().setGlobalComposite(xfermode);
}
+String CanvasRenderingContext2D::filter() const
+{
+ return state().unparsedFilter();
+}
+
+void CanvasRenderingContext2D::setFilter(const String& filterString)
+{
+ if (filterString == state().unparsedFilter())
+ return;
+
+ RefPtrWillBeRawPtr<CSSValue> filterValue = CSSParser::parseSingleValue(CSSPropertyWebkitFilter, filterString, CSSParserContext(HTMLStandardMode, 0));
+
+ if (!filterValue || filterValue->isInitialValue() || filterValue->isInheritedValue())
+ return;
+
+ modifiableState().setUnparsedFilter(filterString);
+ modifiableState().setFilter(filterValue.release());
+}
+
PassRefPtrWillBeRawPtr<SVGMatrixTearOff> CanvasRenderingContext2D::currentTransform() const
{
return SVGMatrixTearOff::create(state().transform());
@@ -816,31 +835,53 @@ static bool isFullCanvasCompositeMode(SkXfermode::Mode op)
}
template<typename DrawFunc>
-void CanvasRenderingContext2D::fullCanvasCompositedDraw(const DrawFunc& drawFunc, CanvasRenderingContext2DState::PaintType paintType, CanvasRenderingContext2DState::ImageType imageType)
+void CanvasRenderingContext2D::compositedDraw(const DrawFunc& drawFunc, CanvasRenderingContext2DState::PaintType paintType, CanvasRenderingContext2DState::ImageType imageType)
{
- ASSERT(isFullCanvasCompositeMode(state().globalComposite()));
+ SkImageFilter* filter = state().getFilter(canvas(), accessFont());
+ ASSERT(isFullCanvasCompositeMode(state().globalComposite()) || filter);
ASSERT(drawingCanvas());
-
- SkPaint layerPaint;
- layerPaint.setXfermodeMode(state().globalComposite());
+ SkMatrix ctm = drawingCanvas()->getTotalMatrix();
+ drawingCanvas()->resetMatrix();
+ SkPaint compositePaint;
+ compositePaint.setXfermodeMode(state().globalComposite());
if (state().shouldDrawShadows()) {
// unroll into two independently composited passes if drawing shadows
- drawingCanvas()->saveLayer(nullptr, &layerPaint);
SkPaint shadowPaint = *state().getPaint(paintType, DrawShadowOnly, imageType);
- shadowPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
- drawFunc(&shadowPaint);
+ int saveCount = drawingCanvas()->getSaveCount();
+ if (filter) {
+ SkPaint filterPaint;
+ filterPaint.setImageFilter(filter);
+ // TODO(junov): crbug.com/502921 We could use primitive bounds if we knew that the filter
+ // does not affect transparent black regions.
+ drawingCanvas()->saveLayer(nullptr, &shadowPaint);
+ drawingCanvas()->saveLayer(nullptr, &filterPaint);
+ SkPaint foregroundPaint = *state().getPaint(paintType, DrawForegroundOnly, imageType);
+ drawingCanvas()->setMatrix(ctm);
+ drawFunc(&foregroundPaint);
+ } else {
+ ASSERT(isFullCanvasCompositeMode(state().globalComposite()));
+ drawingCanvas()->saveLayer(nullptr, &compositePaint);
+ shadowPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
+ drawingCanvas()->setMatrix(ctm);
+ drawFunc(&shadowPaint);
+ }
if (!drawingCanvas())
return;
- drawingCanvas()->restore();
+ drawingCanvas()->restoreToCount(saveCount);
}
- drawingCanvas()->saveLayer(nullptr, &layerPaint);
+ compositePaint.setImageFilter(filter);
+ // TODO(junov): crbug.com/502921 We could use primitive bounds if we knew that the filter
+ // does not affect transparent black regions *and* !isFullCanvasCompositeMode
+ drawingCanvas()->saveLayer(nullptr, &compositePaint);
SkPaint foregroundPaint = *state().getPaint(paintType, DrawForegroundOnly, imageType);
foregroundPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
+ drawingCanvas()->setMatrix(ctm);
drawFunc(&foregroundPaint);
if (!drawingCanvas())
return;
drawingCanvas()->restore();
+ drawingCanvas()->setMatrix(ctm);
}
template<typename DrawFunc, typename ContainsFunc>
@@ -861,8 +902,8 @@ bool CanvasRenderingContext2D::draw(const DrawFunc& drawFunc, const ContainsFunc
return false;
}
- if (isFullCanvasCompositeMode(state().globalComposite())) {
- fullCanvasCompositedDraw(drawFunc, paintType, imageType);
+ if (isFullCanvasCompositeMode(state().globalComposite()) || state().hasFilter()) {
+ compositedDraw(drawFunc, paintType, imageType);
didDraw(clipBounds);
} else if (state().globalComposite() == SkXfermode::kSrc_Mode) {
clearCanvas(); // takes care of checkOvewrdraw()
« no previous file with comments | « Source/core/html/canvas/CanvasRenderingContext2D.h ('k') | Source/core/html/canvas/CanvasRenderingContext2D.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698