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

Unified Diff: Source/core/html/canvas/CanvasRenderingContext2DState.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
« no previous file with comments | « Source/core/html/canvas/CanvasRenderingContext2DState.h ('k') | Source/core/html/canvas/CanvasStyle.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/html/canvas/CanvasRenderingContext2DState.cpp
diff --git a/Source/core/html/canvas/CanvasRenderingContext2DState.cpp b/Source/core/html/canvas/CanvasRenderingContext2DState.cpp
index 5eb0ab5e6835166a51fd77dfa0922ae647fd27b5..668ff912474484234551b8e5dd34e0073461bb00 100644
--- a/Source/core/html/canvas/CanvasRenderingContext2DState.cpp
+++ b/Source/core/html/canvas/CanvasRenderingContext2DState.cpp
@@ -10,7 +10,10 @@
#include "core/html/canvas/CanvasGradient.h"
#include "core/html/canvas/CanvasPattern.h"
#include "core/html/canvas/CanvasStyle.h"
+#include "platform/graphics/DrawLooperBuilder.h"
#include "platform/graphics/skia/SkiaUtils.h"
+#include "third_party/skia/include/effects/SkDashPathEffect.h"
+#include "third_party/skia/include/effects/SkDropShadowImageFilter.h"
static const char defaultFont[] = "10px sans-serif";
@@ -18,27 +21,33 @@ namespace blink {
CanvasRenderingContext2DState::CanvasRenderingContext2DState()
: m_unrealizedSaveCount(0)
- , m_strokeStyle(CanvasStyle::createFromRGBA(Color::black))
- , m_fillStyle(CanvasStyle::createFromRGBA(Color::black))
- , m_lineWidth(1)
- , m_lineCap(ButtCap)
- , m_lineJoin(MiterJoin)
- , m_miterLimit(10)
+ , m_strokeStyle(CanvasStyle::createFromRGBA(SK_ColorBLACK))
+ , m_fillStyle(CanvasStyle::createFromRGBA(SK_ColorBLACK))
, m_shadowBlur(0)
, m_shadowColor(Color::transparent)
, m_globalAlpha(1)
- , m_globalComposite(SkXfermode::kSrcOver_Mode)
- , m_isTransformInvertible(true)
, m_lineDashOffset(0)
- , m_imageSmoothingEnabled(true)
+ , m_unparsedFont(defaultFont)
, m_textAlign(StartTextAlign)
, m_textBaseline(AlphabeticTextBaseline)
, m_direction(DirectionInherit)
- , m_unparsedFont(defaultFont)
, m_realizedFont(false)
+ , m_isTransformInvertible(true)
, m_hasClip(false)
, m_hasComplexClip(false)
+ , m_fillStyleDirty(true)
+ , m_strokeStyleDirty(true)
+ , m_lineDashDirty(false)
{
+ m_fillPaint.setStyle(SkPaint::kFill_Style);
+ m_fillPaint.setAntiAlias(true);
+ m_strokePaint.setStyle(SkPaint::kStroke_Style);
+ m_strokePaint.setStrokeWidth(1);
+ m_strokePaint.setStrokeCap(SkPaint::kButt_Cap);
+ m_strokePaint.setStrokeMiter(10);
+ m_strokePaint.setStrokeJoin(SkPaint::kMiter_Join);
+ m_strokePaint.setAntiAlias(true);
+ setImageSmoothingEnabled(true);
}
CanvasRenderingContext2DState::CanvasRenderingContext2DState(const CanvasRenderingContext2DState& other, ClipListCopyMode mode)
@@ -48,27 +57,31 @@ CanvasRenderingContext2DState::CanvasRenderingContext2DState(const CanvasRenderi
, m_unparsedFillColor(other.m_unparsedFillColor)
, m_strokeStyle(other.m_strokeStyle)
, m_fillStyle(other.m_fillStyle)
- , m_lineWidth(other.m_lineWidth)
- , m_lineCap(other.m_lineCap)
- , m_lineJoin(other.m_lineJoin)
- , m_miterLimit(other.m_miterLimit)
+ , m_strokePaint(other.m_strokePaint)
+ , m_fillPaint(other.m_fillPaint)
, m_shadowOffset(other.m_shadowOffset)
, m_shadowBlur(other.m_shadowBlur)
, m_shadowColor(other.m_shadowColor)
+ , m_emptyDrawLooper(other.m_emptyDrawLooper)
+ , m_shadowOnlyDrawLooper(other.m_shadowOnlyDrawLooper)
+ , m_shadowAndForegroundDrawLooper(other.m_shadowAndForegroundDrawLooper)
+ , m_shadowOnlyImageFilter(other.m_shadowOnlyImageFilter)
+ , m_shadowAndForegroundImageFilter(other.m_shadowAndForegroundImageFilter)
, m_globalAlpha(other.m_globalAlpha)
- , m_globalComposite(other.m_globalComposite)
, m_transform(other.m_transform)
- , m_isTransformInvertible(other.m_isTransformInvertible)
, m_lineDashOffset(other.m_lineDashOffset)
- , m_imageSmoothingEnabled(other.m_imageSmoothingEnabled)
+ , m_unparsedFont(other.m_unparsedFont)
+ , m_font(other.m_font)
, m_textAlign(other.m_textAlign)
, m_textBaseline(other.m_textBaseline)
, m_direction(other.m_direction)
- , m_unparsedFont(other.m_unparsedFont)
- , m_font(other.m_font)
, m_realizedFont(other.m_realizedFont)
+ , m_isTransformInvertible(other.m_isTransformInvertible)
, m_hasClip(other.m_hasClip)
, m_hasComplexClip(other.m_hasComplexClip)
+ , m_fillStyleDirty(other.m_fillStyleDirty)
+ , m_strokeStyleDirty(other.m_strokeStyleDirty)
+ , m_lineDashDirty(other.m_lineDashDirty)
{
if (mode == CopyClipList) {
m_clipList = other.m_clipList;
@@ -92,26 +105,31 @@ CanvasRenderingContext2DState& CanvasRenderingContext2DState::operator=(const Ca
m_unparsedFillColor = other.m_unparsedFillColor;
m_strokeStyle = other.m_strokeStyle;
m_fillStyle = other.m_fillStyle;
- m_lineWidth = other.m_lineWidth;
- m_lineCap = other.m_lineCap;
- m_lineJoin = other.m_lineJoin;
- m_miterLimit = other.m_miterLimit;
+ m_strokePaint = other.m_strokePaint;
+ m_fillPaint = other.m_fillPaint;
m_shadowOffset = other.m_shadowOffset;
m_shadowBlur = other.m_shadowBlur;
m_shadowColor = other.m_shadowColor;
+ m_emptyDrawLooper = other.m_emptyDrawLooper;
+ m_shadowOnlyDrawLooper = other.m_shadowOnlyDrawLooper;
+ m_shadowAndForegroundDrawLooper = other.m_shadowAndForegroundDrawLooper;
+ m_shadowOnlyImageFilter = other.m_shadowOnlyImageFilter;
+ m_shadowAndForegroundImageFilter = other.m_shadowAndForegroundImageFilter;
m_globalAlpha = other.m_globalAlpha;
- m_globalComposite = other.m_globalComposite;
m_transform = other.m_transform;
- m_isTransformInvertible = other.m_isTransformInvertible;
- m_imageSmoothingEnabled = other.m_imageSmoothingEnabled;
+ m_lineDashOffset = other.m_lineDashOffset;
+ m_unparsedFont = other.m_unparsedFont;
+ m_font = other.m_font;
m_textAlign = other.m_textAlign;
m_textBaseline = other.m_textBaseline;
m_direction = other.m_direction;
- m_unparsedFont = other.m_unparsedFont;
- m_font = other.m_font;
m_realizedFont = other.m_realizedFont;
+ m_isTransformInvertible = other.m_isTransformInvertible;
m_hasClip = other.m_hasClip;
m_hasComplexClip = other.m_hasComplexClip;
+ m_fillStyleDirty = other.m_fillStyleDirty;
+ m_strokeStyleDirty = other.m_strokeStyleDirty;
+ m_lineDashDirty = other.m_lineDashDirty;
m_clipList = other.m_clipList;
if (m_realizedFont)
@@ -143,6 +161,12 @@ DEFINE_TRACE(CanvasRenderingContext2DState)
CSSFontSelectorClient::trace(visitor);
}
+void CanvasRenderingContext2DState::setLineDashOffset(float offset)
+{
+ m_lineDashOffset = offset;
+ m_lineDashDirty = true;
+}
+
void CanvasRenderingContext2DState::setLineDash(const Vector<float>& dash)
{
m_lineDash = dash;
@@ -150,6 +174,65 @@ void CanvasRenderingContext2DState::setLineDash(const Vector<float>& dash)
// number of elements is odd
if (dash.size() % 2)
m_lineDash.appendVector(dash);
+
+ m_lineDashDirty = true;
+}
+
+void CanvasRenderingContext2DState::updateLineDash() const
+{
+ if (!m_lineDashDirty)
+ return;
+
+ if (m_lineDash.size() == 0) {
+ m_strokePaint.setPathEffect(0);
+ } else {
+ m_strokePaint.setPathEffect(SkDashPathEffect::Create(m_lineDash.data(), m_lineDash.size(), m_lineDashOffset));
+ }
+
+ m_lineDashDirty = false;
+}
+
+void CanvasRenderingContext2DState::setStrokeStyle(PassRefPtrWillBeRawPtr<CanvasStyle> style)
+{
+ m_strokeStyle = style;
+ m_strokeStyleDirty = true;
+}
+
+void CanvasRenderingContext2DState::setFillStyle(PassRefPtrWillBeRawPtr<CanvasStyle> style)
+{
+ m_fillStyle = style;
+ m_fillStyleDirty = true;
+}
+
+void CanvasRenderingContext2DState::updateStrokeStyle() const
+{
+ if (!m_strokeStyleDirty)
+ return;
+
+ int clampedAlpha = clampedAlphaForBlending(m_globalAlpha);
+ ASSERT(m_strokeStyle);
+ m_strokePaint.setShader(m_strokeStyle->shader());
+ m_strokePaint.setColor(scaleAlpha(m_strokeStyle->paintColor(), clampedAlpha));
+ m_strokeStyleDirty = false;
+}
+
+void CanvasRenderingContext2DState::updateFillStyle() const
+{
+ if (!m_fillStyleDirty)
+ return;
+
+ int clampedAlpha = clampedAlphaForBlending(m_globalAlpha);
+ ASSERT(m_fillStyle);
+ m_fillPaint.setShader(m_fillStyle->shader());
+ m_fillPaint.setColor(scaleAlpha(m_fillStyle->paintColor(), clampedAlpha));
+ m_fillStyleDirty = false;
+}
+
+void CanvasRenderingContext2DState::setGlobalAlpha(float alpha)
+{
+ m_globalAlpha = alpha;
+ m_strokeStyleDirty = true;
+ m_fillStyleDirty = true;
}
void CanvasRenderingContext2DState::clipPath(const SkPath& path, AntiAliasingMode antiAliasingMode)
@@ -190,4 +273,163 @@ void CanvasRenderingContext2DState::resetTransform()
m_isTransformInvertible = true;
}
+SkDrawLooper* CanvasRenderingContext2DState::emptyDrawLooper() const
+{
+ if (!m_emptyDrawLooper) {
+ OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create();
+ m_emptyDrawLooper = drawLooperBuilder->detachDrawLooper();
+ }
+ return m_emptyDrawLooper.get();
+}
+
+SkDrawLooper* CanvasRenderingContext2DState::shadowOnlyDrawLooper() const
+{
+ if (!m_shadowOnlyDrawLooper) {
+ OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create();
+ drawLooperBuilder->addShadow(m_shadowOffset, m_shadowBlur, m_shadowColor, DrawLooperBuilder::ShadowIgnoresTransforms, DrawLooperBuilder::ShadowRespectsAlpha);
+ m_shadowOnlyDrawLooper = drawLooperBuilder->detachDrawLooper();
+ }
+ return m_shadowOnlyDrawLooper.get();
+}
+
+SkDrawLooper* CanvasRenderingContext2DState::shadowAndForegroundDrawLooper() const
+{
+ if (!m_shadowAndForegroundDrawLooper) {
+ OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create();
+ drawLooperBuilder->addShadow(m_shadowOffset, m_shadowBlur, m_shadowColor, DrawLooperBuilder::ShadowIgnoresTransforms, DrawLooperBuilder::ShadowRespectsAlpha);
+ drawLooperBuilder->addUnmodifiedContent();
+ m_shadowAndForegroundDrawLooper = drawLooperBuilder->detachDrawLooper();
+ }
+ return m_shadowAndForegroundDrawLooper.get();
+}
+
+SkImageFilter* CanvasRenderingContext2DState::shadowOnlyImageFilter() const
+{
+ if (!m_shadowOnlyImageFilter) {
+ float sigma = skBlurRadiusToSigma(m_shadowBlur);
+ m_shadowOnlyImageFilter = adoptRef(SkDropShadowImageFilter::Create(m_shadowOffset.width(), m_shadowOffset.height(), sigma, sigma, m_shadowColor, SkDropShadowImageFilter::kDrawShadowOnly_ShadowMode));
+ }
+ return m_shadowOnlyImageFilter.get();
+}
+
+SkImageFilter* CanvasRenderingContext2DState::shadowAndForegroundImageFilter() const
+{
+ if (!m_shadowAndForegroundImageFilter) {
+ float sigma = skBlurRadiusToSigma(m_shadowBlur);
+ m_shadowAndForegroundImageFilter = adoptRef(SkDropShadowImageFilter::Create(m_shadowOffset.width(), m_shadowOffset.height(), sigma, sigma, m_shadowColor, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode));
+ }
+ return m_shadowAndForegroundImageFilter.get();
+}
+
+void CanvasRenderingContext2DState::shadowParameterChanged()
+{
+ m_shadowOnlyDrawLooper.clear();
+ m_shadowAndForegroundDrawLooper.clear();
+ m_shadowOnlyImageFilter.clear();
+ m_shadowAndForegroundImageFilter.clear();
+}
+
+void CanvasRenderingContext2DState::setShadowOffsetX(float x)
+{
+ m_shadowOffset.setWidth(x);
+ shadowParameterChanged();
+}
+
+void CanvasRenderingContext2DState::setShadowOffsetY(float y)
+{
+ m_shadowOffset.setHeight(y);
+ shadowParameterChanged();
+}
+
+void CanvasRenderingContext2DState::setShadowBlur(float shadowBlur)
+{
+ m_shadowBlur = shadowBlur;
+ shadowParameterChanged();
+}
+
+void CanvasRenderingContext2DState::setShadowColor(SkColor shadowColor)
+{
+ m_shadowColor = shadowColor;
+ shadowParameterChanged();
+}
+
+void CanvasRenderingContext2DState::setGlobalComposite(SkXfermode::Mode mode)
+{
+ m_strokePaint.setXfermodeMode(mode);
+ m_fillPaint.setXfermodeMode(mode);
+}
+
+SkXfermode::Mode CanvasRenderingContext2DState::globalComposite() const
+{
+ SkXfermode* xferMode = m_strokePaint.getXfermode();
+ SkXfermode::Mode mode;
+ if (!xferMode || !xferMode->asMode(&mode))
+ return SkXfermode::kSrcOver_Mode;
+ return mode;
+}
+
+void CanvasRenderingContext2DState::setImageSmoothingEnabled(bool enabled)
+{
+ SkFilterQuality filterQuality = enabled ? kLow_SkFilterQuality : kNone_SkFilterQuality;
+ m_strokePaint.setFilterQuality(filterQuality);
+ m_fillPaint.setFilterQuality(filterQuality);
+}
+
+bool CanvasRenderingContext2DState::imageSmoothingEnabled() const
+{
+ return m_strokePaint.getFilterQuality() == kLow_SkFilterQuality;
+}
+
+bool CanvasRenderingContext2DState::shouldDrawShadows() const
+{
+ return alphaChannel(m_shadowColor) && (m_shadowBlur || !m_shadowOffset.isZero());
+}
+
+const SkPaint* CanvasRenderingContext2DState::getPaint(PaintType paintType, ShadowMode shadowMode, OpacityMode bitmapOpacity) const
+{
+ SkPaint* paint;
+ if (paintType == StrokePaintType) {
+ updateLineDash();
+ updateStrokeStyle();
+ paint = &m_strokePaint;
+ } else {
+ updateFillStyle();
+ paint = &m_fillPaint;
+ }
+
+ if ((!shouldDrawShadows() && shadowMode == DrawShadowAndForeground) || shadowMode == DrawForegroundOnly) {
+ paint->setLooper(0);
+ paint->setImageFilter(0);
+ return paint;
+ }
+
+ if (!shouldDrawShadows() && shadowMode == DrawShadowOnly) {
+ paint->setLooper(emptyDrawLooper()); // draw nothing
+ paint->setImageFilter(0);
+ return paint;
+ }
+
+ if (shadowMode == DrawShadowOnly) {
+ if (bitmapOpacity == Opaque) {
+ paint->setLooper(shadowOnlyDrawLooper());
+ paint->setImageFilter(0);
+ return paint;
+ }
+ paint->setLooper(0);
+ paint->setImageFilter(shadowOnlyImageFilter());
+ return paint;
+ }
+
+ ASSERT(shadowMode == DrawShadowAndForeground);
+ if (bitmapOpacity == Opaque) {
+ paint->setLooper(shadowAndForegroundDrawLooper());
+ paint->setImageFilter(0);
+ return paint;
+ }
+
+ paint->setLooper(0);
+ paint->setImageFilter(shadowAndForegroundImageFilter());
+ return paint;
+}
+
} // blink
« no previous file with comments | « Source/core/html/canvas/CanvasRenderingContext2DState.h ('k') | Source/core/html/canvas/CanvasStyle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698