Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 | 6 |
| 7 #include "core/html/canvas/CanvasRenderingContext2DState.h" | 7 #include "core/html/canvas/CanvasRenderingContext2DState.h" |
| 8 | 8 |
| 9 #include "core/css/CSSFontSelector.h" | 9 #include "core/css/CSSFontSelector.h" |
| 10 #include "core/html/canvas/CanvasGradient.h" | 10 #include "core/html/canvas/CanvasGradient.h" |
| 11 #include "core/html/canvas/CanvasPattern.h" | 11 #include "core/html/canvas/CanvasPattern.h" |
| 12 #include "core/html/canvas/CanvasStyle.h" | 12 #include "core/html/canvas/CanvasStyle.h" |
| 13 #include "platform/graphics/DrawLooperBuilder.h" | |
| 13 #include "platform/graphics/skia/SkiaUtils.h" | 14 #include "platform/graphics/skia/SkiaUtils.h" |
| 15 #include "third_party/skia/include/effects/SkDashPathEffect.h" | |
| 16 #include "third_party/skia/include/effects/SkDropShadowImageFilter.h" | |
| 14 | 17 |
| 15 static const char defaultFont[] = "10px sans-serif"; | 18 static const char defaultFont[] = "10px sans-serif"; |
| 16 | 19 |
| 17 namespace blink { | 20 namespace blink { |
| 18 | 21 |
| 19 CanvasRenderingContext2DState::CanvasRenderingContext2DState() | 22 CanvasRenderingContext2DState::CanvasRenderingContext2DState() |
| 20 : m_unrealizedSaveCount(0) | 23 : m_unrealizedSaveCount(0) |
| 21 , m_strokeStyle(CanvasStyle::createFromRGBA(Color::black)) | 24 , m_strokeStyle(CanvasStyle::createFromRGBA(SK_ColorBLACK)) |
| 22 , m_fillStyle(CanvasStyle::createFromRGBA(Color::black)) | 25 , m_fillStyle(CanvasStyle::createFromRGBA(SK_ColorBLACK)) |
| 23 , m_lineWidth(1) | |
| 24 , m_lineCap(ButtCap) | |
| 25 , m_lineJoin(MiterJoin) | |
| 26 , m_miterLimit(10) | |
| 27 , m_shadowBlur(0) | 26 , m_shadowBlur(0) |
| 28 , m_shadowColor(Color::transparent) | 27 , m_shadowColor(Color::transparent) |
| 29 , m_globalAlpha(1) | 28 , m_globalAlpha(1) |
| 30 , m_globalComposite(SkXfermode::kSrcOver_Mode) | |
| 31 , m_isTransformInvertible(true) | |
| 32 , m_lineDashOffset(0) | 29 , m_lineDashOffset(0) |
| 33 , m_imageSmoothingEnabled(true) | 30 , m_unparsedFont(defaultFont) |
| 34 , m_textAlign(StartTextAlign) | 31 , m_textAlign(StartTextAlign) |
| 35 , m_textBaseline(AlphabeticTextBaseline) | 32 , m_textBaseline(AlphabeticTextBaseline) |
| 36 , m_direction(DirectionInherit) | 33 , m_direction(DirectionInherit) |
| 37 , m_unparsedFont(defaultFont) | |
| 38 , m_realizedFont(false) | 34 , m_realizedFont(false) |
| 35 , m_isTransformInvertible(true) | |
| 39 , m_hasClip(false) | 36 , m_hasClip(false) |
| 40 , m_hasComplexClip(false) | 37 , m_hasComplexClip(false) |
| 38 , m_fillStyleDirty(true) | |
| 39 , m_strokeStyleDirty(true) | |
| 40 , m_lineDashDirty(false) | |
| 41 { | 41 { |
| 42 m_fillPaint.setStyle(SkPaint::kFill_Style); | |
| 43 m_fillPaint.setAntiAlias(true); | |
| 44 m_strokePaint.setStyle(SkPaint::kStroke_Style); | |
| 45 m_strokePaint.setStrokeWidth(1); | |
| 46 m_strokePaint.setStrokeCap(SkPaint::kButt_Cap); | |
| 47 m_strokePaint.setStrokeMiter(10); | |
| 48 m_strokePaint.setStrokeJoin(SkPaint::kMiter_Join); | |
| 49 m_strokePaint.setAntiAlias(true); | |
| 50 setImageSmoothingEnabled(true); | |
| 42 } | 51 } |
| 43 | 52 |
| 44 CanvasRenderingContext2DState::CanvasRenderingContext2DState(const CanvasRenderi ngContext2DState& other, ClipListCopyMode mode) | 53 CanvasRenderingContext2DState::CanvasRenderingContext2DState(const CanvasRenderi ngContext2DState& other, ClipListCopyMode mode) |
| 45 : CSSFontSelectorClient() | 54 : CSSFontSelectorClient() |
| 46 , m_unrealizedSaveCount(other.m_unrealizedSaveCount) | 55 , m_unrealizedSaveCount(other.m_unrealizedSaveCount) |
| 47 , m_unparsedStrokeColor(other.m_unparsedStrokeColor) | 56 , m_unparsedStrokeColor(other.m_unparsedStrokeColor) |
| 48 , m_unparsedFillColor(other.m_unparsedFillColor) | 57 , m_unparsedFillColor(other.m_unparsedFillColor) |
| 49 , m_strokeStyle(other.m_strokeStyle) | 58 , m_strokeStyle(other.m_strokeStyle) |
| 50 , m_fillStyle(other.m_fillStyle) | 59 , m_fillStyle(other.m_fillStyle) |
| 51 , m_lineWidth(other.m_lineWidth) | 60 , m_strokePaint(other.m_strokePaint) |
| 52 , m_lineCap(other.m_lineCap) | 61 , m_fillPaint(other.m_fillPaint) |
| 53 , m_lineJoin(other.m_lineJoin) | |
| 54 , m_miterLimit(other.m_miterLimit) | |
| 55 , m_shadowOffset(other.m_shadowOffset) | 62 , m_shadowOffset(other.m_shadowOffset) |
| 56 , m_shadowBlur(other.m_shadowBlur) | 63 , m_shadowBlur(other.m_shadowBlur) |
| 57 , m_shadowColor(other.m_shadowColor) | 64 , m_shadowColor(other.m_shadowColor) |
| 65 , m_emptyDrawLooper(other.m_emptyDrawLooper) | |
| 66 , m_shadowOnlyDrawLooper(other.m_shadowOnlyDrawLooper) | |
| 67 , m_shadowAndForegroundDrawLooper(other.m_shadowAndForegroundDrawLooper) | |
| 68 , m_shadowOnlyImageFilter(other.m_shadowOnlyImageFilter) | |
| 69 , m_shadowAndForegroundImageFilter(other.m_shadowAndForegroundImageFilter) | |
| 58 , m_globalAlpha(other.m_globalAlpha) | 70 , m_globalAlpha(other.m_globalAlpha) |
| 59 , m_globalComposite(other.m_globalComposite) | |
| 60 , m_transform(other.m_transform) | 71 , m_transform(other.m_transform) |
| 61 , m_isTransformInvertible(other.m_isTransformInvertible) | |
| 62 , m_lineDashOffset(other.m_lineDashOffset) | 72 , m_lineDashOffset(other.m_lineDashOffset) |
| 63 , m_imageSmoothingEnabled(other.m_imageSmoothingEnabled) | 73 , m_unparsedFont(other.m_unparsedFont) |
| 74 , m_font(other.m_font) | |
| 64 , m_textAlign(other.m_textAlign) | 75 , m_textAlign(other.m_textAlign) |
| 65 , m_textBaseline(other.m_textBaseline) | 76 , m_textBaseline(other.m_textBaseline) |
| 66 , m_direction(other.m_direction) | 77 , m_direction(other.m_direction) |
| 67 , m_unparsedFont(other.m_unparsedFont) | |
| 68 , m_font(other.m_font) | |
| 69 , m_realizedFont(other.m_realizedFont) | 78 , m_realizedFont(other.m_realizedFont) |
| 79 , m_isTransformInvertible(other.m_isTransformInvertible) | |
| 70 , m_hasClip(other.m_hasClip) | 80 , m_hasClip(other.m_hasClip) |
| 71 , m_hasComplexClip(other.m_hasComplexClip) | 81 , m_hasComplexClip(other.m_hasComplexClip) |
| 82 , m_fillStyleDirty(other.m_fillStyleDirty) | |
| 83 , m_strokeStyleDirty(other.m_strokeStyleDirty) | |
| 84 , m_lineDashDirty(other.m_lineDashDirty) | |
| 72 { | 85 { |
| 73 if (mode == CopyClipList) { | 86 if (mode == CopyClipList) { |
| 74 m_clipList = other.m_clipList; | 87 m_clipList = other.m_clipList; |
| 75 } | 88 } |
| 76 if (m_realizedFont) | 89 if (m_realizedFont) |
| 77 static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalid ationCallbacks(this); | 90 static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalid ationCallbacks(this); |
| 78 } | 91 } |
| 79 | 92 |
| 80 CanvasRenderingContext2DState& CanvasRenderingContext2DState::operator=(const Ca nvasRenderingContext2DState& other) | 93 CanvasRenderingContext2DState& CanvasRenderingContext2DState::operator=(const Ca nvasRenderingContext2DState& other) |
| 81 { | 94 { |
| 82 if (this == &other) | 95 if (this == &other) |
| 83 return *this; | 96 return *this; |
| 84 | 97 |
| 85 #if !ENABLE(OILPAN) | 98 #if !ENABLE(OILPAN) |
| 86 if (m_realizedFont) | 99 if (m_realizedFont) |
| 87 static_cast<CSSFontSelector*>(m_font.fontSelector())->unregisterForInval idationCallbacks(this); | 100 static_cast<CSSFontSelector*>(m_font.fontSelector())->unregisterForInval idationCallbacks(this); |
| 88 #endif | 101 #endif |
| 89 | 102 |
| 90 m_unrealizedSaveCount = other.m_unrealizedSaveCount; | 103 m_unrealizedSaveCount = other.m_unrealizedSaveCount; |
| 91 m_unparsedStrokeColor = other.m_unparsedStrokeColor; | 104 m_unparsedStrokeColor = other.m_unparsedStrokeColor; |
| 92 m_unparsedFillColor = other.m_unparsedFillColor; | 105 m_unparsedFillColor = other.m_unparsedFillColor; |
| 93 m_strokeStyle = other.m_strokeStyle; | 106 m_strokeStyle = other.m_strokeStyle; |
| 94 m_fillStyle = other.m_fillStyle; | 107 m_fillStyle = other.m_fillStyle; |
| 95 m_lineWidth = other.m_lineWidth; | 108 m_strokePaint = other.m_strokePaint; |
| 96 m_lineCap = other.m_lineCap; | 109 m_fillPaint = other.m_fillPaint; |
| 97 m_lineJoin = other.m_lineJoin; | |
| 98 m_miterLimit = other.m_miterLimit; | |
| 99 m_shadowOffset = other.m_shadowOffset; | 110 m_shadowOffset = other.m_shadowOffset; |
| 100 m_shadowBlur = other.m_shadowBlur; | 111 m_shadowBlur = other.m_shadowBlur; |
| 101 m_shadowColor = other.m_shadowColor; | 112 m_shadowColor = other.m_shadowColor; |
| 113 m_emptyDrawLooper = other.m_emptyDrawLooper; | |
| 114 m_shadowOnlyDrawLooper = other.m_shadowOnlyDrawLooper; | |
| 115 m_shadowAndForegroundDrawLooper = other.m_shadowAndForegroundDrawLooper; | |
| 116 m_shadowOnlyImageFilter = other.m_shadowOnlyImageFilter; | |
| 117 m_shadowAndForegroundImageFilter = other.m_shadowAndForegroundImageFilter; | |
| 102 m_globalAlpha = other.m_globalAlpha; | 118 m_globalAlpha = other.m_globalAlpha; |
| 103 m_globalComposite = other.m_globalComposite; | |
| 104 m_transform = other.m_transform; | 119 m_transform = other.m_transform; |
| 105 m_isTransformInvertible = other.m_isTransformInvertible; | 120 m_lineDashOffset = other.m_lineDashOffset; |
| 106 m_imageSmoothingEnabled = other.m_imageSmoothingEnabled; | 121 m_unparsedFont = other.m_unparsedFont; |
| 122 m_font = other.m_font; | |
| 107 m_textAlign = other.m_textAlign; | 123 m_textAlign = other.m_textAlign; |
| 108 m_textBaseline = other.m_textBaseline; | 124 m_textBaseline = other.m_textBaseline; |
| 109 m_direction = other.m_direction; | 125 m_direction = other.m_direction; |
| 110 m_unparsedFont = other.m_unparsedFont; | |
| 111 m_font = other.m_font; | |
| 112 m_realizedFont = other.m_realizedFont; | 126 m_realizedFont = other.m_realizedFont; |
| 127 m_isTransformInvertible = other.m_isTransformInvertible; | |
| 113 m_hasClip = other.m_hasClip; | 128 m_hasClip = other.m_hasClip; |
| 114 m_hasComplexClip = other.m_hasComplexClip; | 129 m_hasComplexClip = other.m_hasComplexClip; |
| 130 m_fillStyleDirty = other.m_fillStyleDirty; | |
| 131 m_strokeStyleDirty = other.m_strokeStyleDirty; | |
| 132 m_lineDashDirty = other.m_lineDashDirty; | |
| 115 m_clipList = other.m_clipList; | 133 m_clipList = other.m_clipList; |
| 116 | 134 |
| 117 if (m_realizedFont) | 135 if (m_realizedFont) |
| 118 static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalid ationCallbacks(this); | 136 static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalid ationCallbacks(this); |
| 119 | 137 |
| 120 return *this; | 138 return *this; |
| 121 } | 139 } |
| 122 | 140 |
| 123 CanvasRenderingContext2DState::~CanvasRenderingContext2DState() | 141 CanvasRenderingContext2DState::~CanvasRenderingContext2DState() |
| 124 { | 142 { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 136 m_font.update(fontSelector); | 154 m_font.update(fontSelector); |
| 137 } | 155 } |
| 138 | 156 |
| 139 DEFINE_TRACE(CanvasRenderingContext2DState) | 157 DEFINE_TRACE(CanvasRenderingContext2DState) |
| 140 { | 158 { |
| 141 visitor->trace(m_strokeStyle); | 159 visitor->trace(m_strokeStyle); |
| 142 visitor->trace(m_fillStyle); | 160 visitor->trace(m_fillStyle); |
| 143 CSSFontSelectorClient::trace(visitor); | 161 CSSFontSelectorClient::trace(visitor); |
| 144 } | 162 } |
| 145 | 163 |
| 164 void CanvasRenderingContext2DState::setLineDashOffset(float offset) | |
| 165 { | |
| 166 m_lineDashOffset = offset; | |
| 167 m_lineDashDirty = true; | |
| 168 } | |
| 169 | |
| 146 void CanvasRenderingContext2DState::setLineDash(const Vector<float>& dash) | 170 void CanvasRenderingContext2DState::setLineDash(const Vector<float>& dash) |
| 147 { | 171 { |
| 148 m_lineDash = dash; | 172 m_lineDash = dash; |
| 149 // Spec requires the concatenation of two copies the dash list when the | 173 // Spec requires the concatenation of two copies the dash list when the |
| 150 // number of elements is odd | 174 // number of elements is odd |
| 151 if (dash.size() % 2) | 175 if (dash.size() % 2) |
| 152 m_lineDash.appendVector(dash); | 176 m_lineDash.appendVector(dash); |
| 177 | |
| 178 m_lineDashDirty = true; | |
| 179 } | |
| 180 | |
| 181 void CanvasRenderingContext2DState::updateLineDash() const | |
| 182 { | |
| 183 if (!m_lineDashDirty) | |
| 184 return; | |
| 185 | |
| 186 if (m_lineDash.size() == 0) { | |
| 187 m_strokePaint.setPathEffect(0); | |
| 188 } else { | |
| 189 m_strokePaint.setPathEffect(SkDashPathEffect::Create(m_lineDash.data(), m_lineDash.size(), m_lineDashOffset)); | |
| 190 } | |
| 191 | |
| 192 m_lineDashDirty = false; | |
| 193 } | |
| 194 | |
| 195 void CanvasRenderingContext2DState::setStrokeStyle(PassRefPtrWillBeRawPtr<Canvas Style> style) | |
| 196 { | |
| 197 m_strokeStyle = style; | |
| 198 m_strokeStyleDirty = true; | |
| 199 } | |
| 200 | |
| 201 void CanvasRenderingContext2DState::setFillStyle(PassRefPtrWillBeRawPtr<CanvasSt yle> style) | |
| 202 { | |
| 203 m_fillStyle = style; | |
| 204 m_fillStyleDirty = true; | |
| 205 } | |
| 206 | |
| 207 void CanvasRenderingContext2DState::updateStrokeStyle() const | |
| 208 { | |
| 209 if (!m_strokeStyleDirty) | |
| 210 return; | |
| 211 | |
| 212 int clampedAlpha = clampedAlphaForBlending(m_globalAlpha); | |
| 213 ASSERT(m_strokeStyle); | |
| 214 m_strokePaint.setShader(m_strokeStyle->shader()); | |
| 215 m_strokePaint.setColor(scaleAlpha(m_strokeStyle->paintColor(), clampedAlpha) ); | |
| 216 m_strokeStyleDirty = false; | |
| 217 } | |
| 218 | |
| 219 void CanvasRenderingContext2DState::updateFillStyle() const | |
| 220 { | |
| 221 if (!m_fillStyleDirty) | |
| 222 return; | |
| 223 | |
| 224 int clampedAlpha = clampedAlphaForBlending(m_globalAlpha); | |
| 225 ASSERT(m_fillStyle); | |
| 226 m_fillPaint.setShader(m_fillStyle->shader()); | |
| 227 m_fillPaint.setColor(scaleAlpha(m_fillStyle->paintColor(), clampedAlpha)); | |
| 228 m_fillStyleDirty = false; | |
| 229 } | |
| 230 | |
| 231 void CanvasRenderingContext2DState::setGlobalAlpha(float alpha) | |
| 232 { | |
| 233 m_globalAlpha = alpha; | |
| 234 m_strokeStyleDirty = true; | |
| 235 m_fillStyleDirty = true; | |
| 153 } | 236 } |
| 154 | 237 |
| 155 void CanvasRenderingContext2DState::clipPath(const SkPath& path, AntiAliasingMod e antiAliasingMode) | 238 void CanvasRenderingContext2DState::clipPath(const SkPath& path, AntiAliasingMod e antiAliasingMode) |
| 156 { | 239 { |
| 157 m_clipList.clipPath(path, antiAliasingMode, affineTransformToSkMatrix(m_tran sform)); | 240 m_clipList.clipPath(path, antiAliasingMode, affineTransformToSkMatrix(m_tran sform)); |
| 158 m_hasClip = true; | 241 m_hasClip = true; |
| 159 if (!path.isRect(0)) | 242 if (!path.isRect(0)) |
| 160 m_hasComplexClip = true; | 243 m_hasComplexClip = true; |
| 161 } | 244 } |
| 162 | 245 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 183 m_isTransformInvertible = transform.isInvertible(); | 266 m_isTransformInvertible = transform.isInvertible(); |
| 184 m_transform = transform; | 267 m_transform = transform; |
| 185 } | 268 } |
| 186 | 269 |
| 187 void CanvasRenderingContext2DState::resetTransform() | 270 void CanvasRenderingContext2DState::resetTransform() |
| 188 { | 271 { |
| 189 m_transform.makeIdentity(); | 272 m_transform.makeIdentity(); |
| 190 m_isTransformInvertible = true; | 273 m_isTransformInvertible = true; |
| 191 } | 274 } |
| 192 | 275 |
| 276 SkDrawLooper* CanvasRenderingContext2DState::emptyDrawLooper() const | |
| 277 { | |
| 278 if (!m_emptyDrawLooper) { | |
| 279 OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create( ); | |
| 280 m_emptyDrawLooper = drawLooperBuilder->detachDrawLooper(); | |
| 281 } | |
| 282 return m_emptyDrawLooper.get(); | |
| 283 } | |
| 284 | |
| 285 SkDrawLooper* CanvasRenderingContext2DState::shadowOnlyDrawLooper() const | |
| 286 { | |
| 287 if (!m_shadowOnlyDrawLooper) { | |
| 288 OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create( ); | |
| 289 drawLooperBuilder->addShadow(m_shadowOffset, m_shadowBlur, m_shadowColor , DrawLooperBuilder::ShadowIgnoresTransforms, DrawLooperBuilder::ShadowRespectsA lpha); | |
| 290 m_shadowOnlyDrawLooper = drawLooperBuilder->detachDrawLooper(); | |
| 291 } | |
| 292 return m_shadowOnlyDrawLooper.get(); | |
| 293 } | |
| 294 | |
| 295 SkDrawLooper* CanvasRenderingContext2DState::shadowAndForegroundDrawLooper() con st | |
| 296 { | |
| 297 if (!m_shadowAndForegroundDrawLooper) { | |
| 298 OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create( ); | |
| 299 drawLooperBuilder->addShadow(m_shadowOffset, m_shadowBlur, m_shadowColor , DrawLooperBuilder::ShadowIgnoresTransforms, DrawLooperBuilder::ShadowRespectsA lpha); | |
| 300 drawLooperBuilder->addUnmodifiedContent(); | |
| 301 m_shadowAndForegroundDrawLooper = drawLooperBuilder->detachDrawLooper(); | |
| 302 } | |
| 303 return m_shadowAndForegroundDrawLooper.get(); | |
| 304 } | |
| 305 | |
| 306 static float shadowBlurToSigma(const float& blur) | |
| 307 { | |
| 308 // These constants are from RadiusToSigma() from DrawLooperBuilder.cpp. | |
|
Stephen White
2015/03/18 22:09:34
Nit: could you expose that function (or move it to
| |
| 309 return 0.288675f * blur + 0.5f; | |
| 310 } | |
| 311 | |
| 312 SkImageFilter* CanvasRenderingContext2DState::shadowOnlyImageFilter() const | |
| 313 { | |
| 314 if (!m_shadowOnlyImageFilter) { | |
| 315 float sigma = shadowBlurToSigma(m_shadowBlur); | |
| 316 m_shadowOnlyImageFilter = adoptRef(SkDropShadowImageFilter::Create(m_sha dowOffset.width(), m_shadowOffset.height(), sigma, sigma, m_shadowColor, SkDropS hadowImageFilter::kDrawShadowOnly_ShadowMode)); | |
| 317 } | |
| 318 return m_shadowOnlyImageFilter.get(); | |
| 319 } | |
| 320 | |
| 321 SkImageFilter* CanvasRenderingContext2DState::shadowAndForegroundImageFilter() c onst | |
| 322 { | |
| 323 if (!m_shadowAndForegroundImageFilter) { | |
| 324 float sigma = shadowBlurToSigma(m_shadowBlur); | |
| 325 m_shadowAndForegroundImageFilter = adoptRef(SkDropShadowImageFilter::Cre ate(m_shadowOffset.width(), m_shadowOffset.height(), sigma, sigma, m_shadowColor , SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode)); | |
| 326 } | |
| 327 return m_shadowAndForegroundImageFilter.get(); | |
| 328 } | |
| 329 | |
| 330 void CanvasRenderingContext2DState::shadowParameterChanged() | |
| 331 { | |
| 332 m_shadowOnlyDrawLooper.clear(); | |
| 333 m_shadowAndForegroundDrawLooper.clear(); | |
| 334 m_shadowOnlyImageFilter.clear(); | |
| 335 m_shadowAndForegroundImageFilter.clear(); | |
| 336 } | |
| 337 | |
| 338 void CanvasRenderingContext2DState::setShadowOffsetX(float x) | |
| 339 { | |
| 340 m_shadowOffset.setWidth(x); | |
| 341 shadowParameterChanged(); | |
| 342 } | |
| 343 | |
| 344 void CanvasRenderingContext2DState::setShadowOffsetY(float y) | |
| 345 { | |
| 346 m_shadowOffset.setHeight(y); | |
| 347 shadowParameterChanged(); | |
| 348 } | |
| 349 | |
| 350 void CanvasRenderingContext2DState::setShadowBlur(float shadowBlur) | |
| 351 { | |
| 352 m_shadowBlur = shadowBlur; | |
| 353 shadowParameterChanged(); | |
| 354 } | |
| 355 | |
| 356 void CanvasRenderingContext2DState::setShadowColor(SkColor shadowColor) | |
| 357 { | |
| 358 m_shadowColor = shadowColor; | |
| 359 shadowParameterChanged(); | |
| 360 } | |
| 361 | |
| 362 void CanvasRenderingContext2DState::setGlobalComposite(SkXfermode::Mode mode) | |
| 363 { | |
| 364 m_strokePaint.setXfermodeMode(mode); | |
| 365 m_fillPaint.setXfermodeMode(mode); | |
| 366 } | |
| 367 | |
| 368 SkXfermode::Mode CanvasRenderingContext2DState::globalComposite() const | |
| 369 { | |
| 370 SkXfermode* xferMode = m_strokePaint.getXfermode(); | |
| 371 SkXfermode::Mode mode; | |
| 372 if (!xferMode || !xferMode->asMode(&mode)) | |
| 373 return SkXfermode::kSrcOver_Mode; | |
| 374 return mode; | |
| 375 } | |
| 376 | |
| 377 void CanvasRenderingContext2DState::setImageSmoothingEnabled(bool enabled) | |
| 378 { | |
| 379 SkFilterQuality filterQuality = enabled ? kLow_SkFilterQuality : kNone_SkFil terQuality; | |
| 380 m_strokePaint.setFilterQuality(filterQuality); | |
| 381 m_fillPaint.setFilterQuality(filterQuality); | |
| 382 } | |
| 383 | |
| 384 bool CanvasRenderingContext2DState::imageSmoothingEnabled() const | |
| 385 { | |
| 386 return m_strokePaint.getFilterQuality() == kLow_SkFilterQuality; | |
| 387 } | |
| 388 | |
| 389 bool CanvasRenderingContext2DState::shouldDrawShadows() const | |
| 390 { | |
| 391 return alphaChannel(m_shadowColor) && (m_shadowBlur || !m_shadowOffset.isZer o()); | |
| 392 } | |
| 393 | |
| 394 const SkPaint* CanvasRenderingContext2DState::skPaint(CanvasPaintType paintType, ShadowMode shadowMode, CanvasShadowStrategy shadowStrategy) const | |
| 395 { | |
| 396 SkPaint* paint; | |
| 397 if (paintType == StrokePaintType) { | |
| 398 updateLineDash(); | |
| 399 updateStrokeStyle(); | |
| 400 paint = &m_strokePaint; | |
| 401 } else { | |
| 402 updateFillStyle(); | |
| 403 paint = &m_fillPaint; | |
| 404 } | |
| 405 | |
| 406 if ((!shouldDrawShadows() && shadowMode == DrawShadowAndForeground) || shado wMode == DrawForegroundOnly) { | |
| 407 paint->setLooper(0); | |
| 408 paint->setImageFilter(0); | |
| 409 return paint; | |
| 410 } | |
| 411 | |
| 412 if (!shouldDrawShadows() && shadowMode == DrawShadowOnly) { | |
| 413 paint->setLooper(emptyDrawLooper()); // draw nothing | |
| 414 paint->setImageFilter(0); | |
| 415 return paint; | |
| 416 } | |
| 417 | |
| 418 if (shadowMode == DrawShadowOnly) { | |
| 419 if (shadowStrategy == DrawLooperShadowStrategy) { | |
| 420 paint->setLooper(shadowOnlyDrawLooper()); | |
| 421 paint->setImageFilter(0); | |
| 422 return paint; | |
| 423 } | |
| 424 paint->setLooper(0); | |
| 425 paint->setImageFilter(shadowOnlyImageFilter()); | |
| 426 return paint; | |
| 427 } | |
| 428 | |
| 429 ASSERT(shadowMode == DrawShadowAndForeground); | |
| 430 if (shadowStrategy == DrawLooperShadowStrategy) { | |
| 431 paint->setLooper(shadowAndForegroundDrawLooper()); | |
| 432 paint->setImageFilter(0); | |
| 433 return paint; | |
| 434 } | |
| 435 | |
| 436 paint->setLooper(0); | |
| 437 paint->setImageFilter(shadowAndForegroundImageFilter()); | |
| 438 return paint; | |
| 439 } | |
| 440 | |
| 193 } // blink | 441 } // blink |
| OLD | NEW |