1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "config.h" 6 #include "platform/graphics/GraphicsContextState.h" 7 8 #include "platform/graphics/skia/SkiaUtils.h" 9 10 namespace WebCore { 11 12 GraphicsContextState::GraphicsContextState() 13 : m_fillColor(Color::black) 14 , m_fillRule(RULE_NONZERO) 15 , m_textDrawingMode(TextModeFill) 16 , m_alpha(256) 17 , m_xferMode(nullptr) 18 , m_compositeOperator(CompositeSourceOver) 19 , m_blendMode(blink::WebBlendModeNormal) 20 , m_interpolationQuality(InterpolationDefault) 21 , m_saveCount(0) 22 , m_shouldAntialias(true) 23 , m_shouldSmoothFonts(true) 24 , m_shouldClampToSourceRect(true) 25 { 26 m_strokePaint.setStyle(SkPaint::kStroke_Style); 27 m_strokePaint.setStrokeWidth(SkFloatToScalar(m_strokeData.thickness())); 28 m_strokePaint.setColor(applyAlpha(m_strokeData.color().rgb())); 29 m_strokePaint.setStrokeCap(SkPaint::kDefault_Cap); 30 m_strokePaint.setStrokeJoin(SkPaint::kDefault_Join); 31 m_strokePaint.setStrokeMiter(SkFloatToScalar(m_strokeData.miterLimit())); 32 m_strokePaint.setFilterLevel(WebCoreInterpolationQualityToSkFilterLevel(m_interpolationQuality)); 33 m_strokePaint.setAntiAlias(m_shouldAntialias); 34 m_fillPaint.setColor(applyAlpha(m_fillColor.rgb())); 35 m_fillPaint.setFilterLevel(WebCoreInterpolationQualityToSkFilterLevel(m_interpolationQuality)); 36 m_fillPaint.setAntiAlias(m_shouldAntialias); 37 } 38 39 GraphicsContextState::GraphicsContextState(const GraphicsContextState& other) 40 : m_strokePaint(other.m_strokePaint) 41 , m_fillPaint(other.m_fillPaint) 42 , m_strokeData(other.m_strokeData) 43 , m_fillColor(other.m_fillColor) 44 , m_fillRule(other.m_fillRule) 45 , m_fillGradient(other.m_fillGradient) 46 , m_fillPattern(other.m_fillPattern) 47 , m_looper(other.m_looper) 48 , m_textDrawingMode(other.m_textDrawingMode) 49 , m_alpha(other.m_alpha) 50 , m_xferMode(other.m_xferMode) 51 , m_colorFilter(other.m_colorFilter) 52 , m_compositeOperator(other.m_compositeOperator) 53 , m_blendMode(other.m_blendMode) 54 , m_interpolationQuality(other.m_interpolationQuality) 55 , m_saveCount(0) 56 , m_shouldAntialias(other.m_shouldAntialias) 57 , m_shouldSmoothFonts(other.m_shouldSmoothFonts) 58 , m_shouldClampToSourceRect(other.m_shouldClampToSourceRect) { } 59 60 void GraphicsContextState::copy(const GraphicsContextState& source) 61 { 62 this->~GraphicsContextState(); 63 new (this) GraphicsContextState(source); 64 } 65 66 const SkPaint& GraphicsContextState::strokePaint(int strokedPathLength) const 67 { 68 if (m_strokeData.gradient() && m_strokeData.gradient()->shaderChanged()) 69 m_strokePaint.setShader(m_strokeData.gradient()->shader()); 70 m_strokeData.setupPaintDashPathEffect(&m_strokePaint, strokedPathLength); 71 return m_strokePaint; 72 } 73 74 const SkPaint& GraphicsContextState::fillPaint() const 75 { 76 if (m_fillGradient && m_fillGradient->shaderChanged()) 77 m_fillPaint.setShader(m_fillGradient->shader()); 78 return m_fillPaint; 79 } 80 81 void GraphicsContextState::setStrokeStyle(StrokeStyle style) 82 { 83 m_strokeData.setStyle(style); 84 } 85 86 void GraphicsContextState::setStrokeThickness(float thickness) 87 { 88 m_strokeData.setThickness(thickness); 89 m_strokePaint.setStrokeWidth(SkFloatToScalar(thickness)); 90 } 91 92 void GraphicsContextState::setStrokeColor(const Color& color) 93 { 94 m_strokeData.clearGradient(); 95 m_strokeData.clearPattern(); 96 m_strokeData.setColor(color); 97 m_strokePaint.setColor(applyAlpha(color.rgb())); 98 m_strokePaint.setShader(0); 99 } 100 101 void GraphicsContextState::setStrokeGradient(const PassRefPtr<Gradient> gradient) 102 { 103 m_strokeData.setColor(Color::black); 104 m_strokeData.clearPattern(); 105 m_strokeData.setGradient(gradient); 106 m_strokePaint.setColor(applyAlpha(SK_ColorBLACK)); 107 m_strokePaint.setShader(m_strokeData.gradient()->shader()); 108 } 109 110 void GraphicsContextState::clearStrokeGradient() 111 { 112 m_strokeData.clearGradient(); 113 ASSERT(!m_strokeData.pattern()); 114 m_strokePaint.setColor(applyAlpha(m_strokeData.color().rgb())); 115 } 116 117 void GraphicsContextState::setStrokePattern(const PassRefPtr<Pattern> pattern) 118 { 119 m_strokeData.setColor(Color::black); 120 m_strokeData.clearGradient(); 121 m_strokeData.setPattern(pattern); 122 m_strokePaint.setColor(applyAlpha(SK_ColorBLACK)); 123 m_strokePaint.setShader(m_strokeData.pattern()->shader()); 124 } 125 126 void GraphicsContextState::clearStrokePattern() 127 { 128 m_strokeData.clearPattern(); 129 ASSERT(!m_strokeData.gradient()); 130 m_strokePaint.setColor(applyAlpha(m_strokeData.color().rgb())); 131 } 132 133 void GraphicsContextState::setLineCap(LineCap cap) 134 { 135 m_strokeData.setLineCap(cap); 136 m_strokePaint.setStrokeCap((SkPaint::Cap)cap); 137 } 138 139 void GraphicsContextState::setLineJoin(LineJoin join) 140 { 141 m_strokeData.setLineJoin(join); 142 m_strokePaint.setStrokeJoin((SkPaint::Join)join); 143 } 144 145 void GraphicsContextState::setMiterLimit(float miterLimit) 146 { 147 m_strokeData.setMiterLimit(miterLimit); 148 m_strokePaint.setStrokeMiter(SkFloatToScalar(miterLimit)); 149 } 150 151 void GraphicsContextState::setFillColor(const Color& color) 152 { 153 m_fillColor = color; 154 m_fillGradient.clear(); 155 m_fillPattern.clear(); 156 m_fillPaint.setColor(applyAlpha(color.rgb())); 157 m_fillPaint.setShader(0); 158 } 159 160 void GraphicsContextState::setFillGradient(const PassRefPtr<Gradient> gradient) 161 { 162 m_fillColor = Color::black; 163 m_fillPattern.clear(); 164 m_fillGradient = gradient; 165 m_fillPaint.setColor(applyAlpha(SK_ColorBLACK)); 166 m_fillPaint.setShader(m_fillGradient->shader()); 167 } 168 169 void GraphicsContextState::clearFillGradient() 170 { 171 m_fillGradient.clear(); 172 ASSERT(!m_fillPattern); 173 m_fillPaint.setColor(applyAlpha(m_fillColor.rgb())); 174 } 175 176 void GraphicsContextState::setFillPattern(const PassRefPtr<Pattern> pattern) 177 { 178 m_fillColor = Color::black; 179 m_fillGradient.clear(); 180 m_fillPattern = pattern; 181 m_fillPaint.setColor(applyAlpha(SK_ColorBLACK)); 182 m_fillPaint.setShader(m_fillPattern->shader()); 183 } 184 185 void GraphicsContextState::clearFillPattern() 186 { 187 m_fillPattern.clear(); 188 ASSERT(!m_fillGradient); 189 m_fillPaint.setColor(applyAlpha(m_fillColor.rgb())); 190 } 191 192 // Shadow. (This will need tweaking if we use draw loopers for other things.) 193 void GraphicsContextState::setDrawLooper(PassRefPtr<SkDrawLooper> drawLooper) 194 { 195 m_looper = drawLooper; 196 m_strokePaint.setLooper(m_looper.get()); 197 m_fillPaint.setLooper(m_looper.get()); 198 } 199 200 void GraphicsContextState::clearDrawLooper() 201 { 202 m_looper.clear(); 203 m_strokePaint.setLooper(0); 204 m_fillPaint.setLooper(0); 205 } 206 207 void GraphicsContextState::setAlphaAsFloat(float alpha) 208 { 209 if (alpha < 0) { 210 m_alpha = 0; 211 } else { 212 m_alpha = roundf(alpha * 256); 213 if (m_alpha > 256) 214 m_alpha = 256; 215 } 216 m_strokePaint.setColor(applyAlpha(m_strokeData.color().rgb())); 217 m_fillPaint.setColor(applyAlpha(m_fillColor.rgb())); 218 } 219 220 void GraphicsContextState::setLineDash(const DashArray& dashes, float dashOffset) 221 { 222 m_strokeData.setLineDash(dashes, dashOffset); 223 } 224 225 void GraphicsContextState::setColorFilter(PassRefPtr<SkColorFilter> colorFilter) 226 { 227 m_colorFilter = colorFilter; 228 m_strokePaint.setColorFilter(m_colorFilter.get()); 229 m_fillPaint.setColorFilter(m_colorFilter.get()); 230 } 231 232 void GraphicsContextState::setCompositeOperation(CompositeOperator compositeOperation, blink::WebBlendMode blendMode) 233 { 234 m_compositeOperator = compositeOperation; 235 m_blendMode = blendMode; 236 m_xferMode = WebCoreCompositeToSkiaComposite(compositeOperation, blendMode); 237 m_strokePaint.setXfermode(m_xferMode.get()); 238 m_fillPaint.setXfermode(m_xferMode.get()); 239 } 240 241 void GraphicsContextState::setInterpolationQuality(InterpolationQuality quality) 242 { 243 m_interpolationQuality = quality; 244 m_strokePaint.setFilterLevel(WebCoreInterpolationQualityToSkFilterLevel(quality)); 245 m_fillPaint.setFilterLevel(WebCoreInterpolationQualityToSkFilterLevel(quality)); 246 } 247 248 void GraphicsContextState::setShouldAntialias(bool shouldAntialias) 249 { 250 m_shouldAntialias = shouldAntialias; 251 m_strokePaint.setAntiAlias(shouldAntialias); 252 m_fillPaint.setAntiAlias(shouldAntialias); 253 } 254 255 256 } // namespace WebCore 257