// Copyright (c) 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "flutter/sky/engine/platform/graphics/GraphicsContextState.h" #include "flutter/sky/engine/platform/graphics/skia/SkiaUtils.h" namespace blink { GraphicsContextState::GraphicsContextState() : m_fillColor(Color::black) , m_fillRule(RULE_NONZERO) , m_textDrawingMode(TextModeFill) , m_alpha(256) , m_compositeOperator(CompositeSourceOver) , m_blendMode(WebBlendModeNormal) , m_interpolationQuality(InterpolationDefault) , m_saveCount(0) , m_shouldAntialias(true) , m_shouldClampToSourceRect(true) { m_strokePaint.setStyle(SkPaint::kStroke_Style); m_strokePaint.setStrokeWidth(SkFloatToScalar(m_strokeData.thickness())); m_strokePaint.setColor(applyAlpha(m_strokeData.color().rgb())); m_strokePaint.setStrokeCap(SkPaint::kDefault_Cap); m_strokePaint.setStrokeJoin(SkPaint::kDefault_Join); m_strokePaint.setStrokeMiter(SkFloatToScalar(m_strokeData.miterLimit())); m_strokePaint.setFilterQuality(WebCoreInterpolationQualityToSkFilterQuality(m_interpolationQuality)); m_strokePaint.setAntiAlias(m_shouldAntialias); m_fillPaint.setColor(applyAlpha(m_fillColor.rgb())); m_fillPaint.setFilterQuality(WebCoreInterpolationQualityToSkFilterQuality(m_interpolationQuality)); m_fillPaint.setAntiAlias(m_shouldAntialias); } GraphicsContextState::GraphicsContextState(const GraphicsContextState& other) : m_strokePaint(other.m_strokePaint) , m_fillPaint(other.m_fillPaint) , m_strokeData(other.m_strokeData) , m_fillColor(other.m_fillColor) , m_fillRule(other.m_fillRule) , m_fillGradient(other.m_fillGradient) , m_fillPattern(other.m_fillPattern) , m_looper(other.m_looper) , m_textDrawingMode(other.m_textDrawingMode) , m_alpha(other.m_alpha) , m_colorFilter(other.m_colorFilter) , m_compositeOperator(other.m_compositeOperator) , m_blendMode(other.m_blendMode) , m_interpolationQuality(other.m_interpolationQuality) , m_saveCount(0) , m_shouldAntialias(other.m_shouldAntialias) , m_shouldClampToSourceRect(other.m_shouldClampToSourceRect) { } void GraphicsContextState::copy(const GraphicsContextState& source) { this->~GraphicsContextState(); new (this) GraphicsContextState(source); } const SkPaint& GraphicsContextState::strokePaint(int strokedPathLength) const { if (m_strokeData.gradient() && m_strokeData.gradient()->shaderChanged()) m_strokePaint.setShader(m_strokeData.gradient()->shader()); m_strokeData.setupPaintDashPathEffect(&m_strokePaint, strokedPathLength); return m_strokePaint; } const SkPaint& GraphicsContextState::fillPaint() const { if (m_fillGradient && m_fillGradient->shaderChanged()) m_fillPaint.setShader(m_fillGradient->shader()); return m_fillPaint; } void GraphicsContextState::setStrokeStyle(StrokeStyle style) { m_strokeData.setStyle(style); } void GraphicsContextState::setStrokeThickness(float thickness) { m_strokeData.setThickness(thickness); m_strokePaint.setStrokeWidth(SkFloatToScalar(thickness)); } void GraphicsContextState::setStrokeColor(const Color& color) { m_strokeData.clearGradient(); m_strokeData.clearPattern(); m_strokeData.setColor(color); m_strokePaint.setColor(applyAlpha(color.rgb())); m_strokePaint.setShader(0); } void GraphicsContextState::setStrokeGradient(const PassRefPtr gradient) { m_strokeData.setColor(Color::black); m_strokeData.clearPattern(); m_strokeData.setGradient(gradient); m_strokePaint.setColor(applyAlpha(SK_ColorBLACK)); m_strokePaint.setShader(m_strokeData.gradient()->shader()); } void GraphicsContextState::clearStrokeGradient() { m_strokeData.clearGradient(); ASSERT(!m_strokeData.pattern()); m_strokePaint.setColor(applyAlpha(m_strokeData.color().rgb())); } void GraphicsContextState::setStrokePattern(const PassRefPtr pattern) { m_strokeData.setColor(Color::black); m_strokeData.clearGradient(); m_strokeData.setPattern(pattern); m_strokePaint.setColor(applyAlpha(SK_ColorBLACK)); m_strokePaint.setShader(sk_ref_sp(m_strokeData.pattern()->shader())); } void GraphicsContextState::clearStrokePattern() { m_strokeData.clearPattern(); ASSERT(!m_strokeData.gradient()); m_strokePaint.setColor(applyAlpha(m_strokeData.color().rgb())); } void GraphicsContextState::setLineCap(LineCap cap) { m_strokeData.setLineCap(cap); m_strokePaint.setStrokeCap((SkPaint::Cap)cap); } void GraphicsContextState::setLineJoin(LineJoin join) { m_strokeData.setLineJoin(join); m_strokePaint.setStrokeJoin((SkPaint::Join)join); } void GraphicsContextState::setMiterLimit(float miterLimit) { m_strokeData.setMiterLimit(miterLimit); m_strokePaint.setStrokeMiter(SkFloatToScalar(miterLimit)); } void GraphicsContextState::setFillColor(const Color& color) { m_fillColor = color; m_fillGradient.clear(); m_fillPattern.clear(); m_fillPaint.setColor(applyAlpha(color.rgb())); m_fillPaint.setShader(0); } void GraphicsContextState::setFillGradient(const PassRefPtr gradient) { m_fillColor = Color::black; m_fillPattern.clear(); m_fillGradient = gradient; m_fillPaint.setColor(applyAlpha(SK_ColorBLACK)); m_fillPaint.setShader(m_fillGradient->shader()); } void GraphicsContextState::clearFillGradient() { m_fillGradient.clear(); ASSERT(!m_fillPattern); m_fillPaint.setColor(applyAlpha(m_fillColor.rgb())); } void GraphicsContextState::setFillPattern(const PassRefPtr pattern) { m_fillColor = Color::black; m_fillGradient.clear(); m_fillPattern = pattern; m_fillPaint.setColor(applyAlpha(SK_ColorBLACK)); m_fillPaint.setShader(sk_ref_sp(m_fillPattern->shader())); } void GraphicsContextState::clearFillPattern() { m_fillPattern.clear(); ASSERT(!m_fillGradient); m_fillPaint.setColor(applyAlpha(m_fillColor.rgb())); } // Shadow. (This will need tweaking if we use draw loopers for other things.) void GraphicsContextState::setDrawLooper(sk_sp drawLooper) { m_looper = drawLooper; m_strokePaint.setLooper(m_looper); m_fillPaint.setLooper(m_looper); } void GraphicsContextState::clearDrawLooper() { m_looper.reset(); m_strokePaint.setLooper(nullptr); m_fillPaint.setLooper(nullptr); } void GraphicsContextState::setAlphaAsFloat(float alpha) { if (alpha < 0) { m_alpha = 0; } else { m_alpha = roundf(alpha * 256); if (m_alpha > 256) m_alpha = 256; } m_strokePaint.setColor(applyAlpha(m_strokeData.color().rgb())); m_fillPaint.setColor(applyAlpha(m_fillColor.rgb())); } void GraphicsContextState::setLineDash(const DashArray& dashes, float dashOffset) { m_strokeData.setLineDash(dashes, dashOffset); } void GraphicsContextState::setColorFilter(sk_sp colorFilter) { m_colorFilter = colorFilter; m_strokePaint.setColorFilter(m_colorFilter); m_fillPaint.setColorFilter(m_colorFilter); } void GraphicsContextState::setCompositeOperation(CompositeOperator compositeOperation, WebBlendMode blendMode) { m_compositeOperator = compositeOperation; m_blendMode = blendMode; SkXfermode::Mode xferMode = WebCoreCompositeToSkiaComposite(compositeOperation, blendMode); m_strokePaint.setXfermodeMode(xferMode); m_fillPaint.setXfermodeMode(xferMode); } void GraphicsContextState::setInterpolationQuality(InterpolationQuality quality) { m_interpolationQuality = quality; m_strokePaint.setFilterQuality(WebCoreInterpolationQualityToSkFilterQuality(quality)); m_fillPaint.setFilterQuality(WebCoreInterpolationQualityToSkFilterQuality(quality)); } void GraphicsContextState::setShouldAntialias(bool shouldAntialias) { m_shouldAntialias = shouldAntialias; m_strokePaint.setAntiAlias(shouldAntialias); m_fillPaint.setAntiAlias(shouldAntialias); } } // namespace blink