// 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; SkBlendMode skiaBlendMode = WebCoreCompositeToSkiaComposite(compositeOperation, blendMode); m_strokePaint.setBlendMode(skiaBlendMode); m_fillPaint.setBlendMode(skiaBlendMode); } 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