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 "third_party/blink/renderer/platform/graphics/graphics_context_state.h"
6 
7 #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
8 
9 namespace blink {
10 
FilterQualityForPaint(InterpolationQuality quality)11 static inline SkFilterQuality FilterQualityForPaint(
12     InterpolationQuality quality) {
13   // The filter quality "selected" here will primarily be used when painting a
14   // primitive using one of the PaintFlags below. For the most part this will
15   // not affect things that are part of the Image class hierarchy (which use
16   // the unmodified m_interpolationQuality.)
17   return quality != kInterpolationNone ? kLow_SkFilterQuality
18                                        : kNone_SkFilterQuality;
19 }
20 
GraphicsContextState()21 GraphicsContextState::GraphicsContextState()
22     : text_drawing_mode_(kTextModeFill),
23       interpolation_quality_(kInterpolationDefault),
24       save_count_(0),
25       should_antialias_(true) {
26   stroke_flags_.setStyle(PaintFlags::kStroke_Style);
27   stroke_flags_.setStrokeWidth(SkFloatToScalar(stroke_data_.Thickness()));
28   stroke_flags_.setStrokeCap(PaintFlags::kDefault_Cap);
29   stroke_flags_.setStrokeJoin(PaintFlags::kDefault_Join);
30   stroke_flags_.setStrokeMiter(SkFloatToScalar(stroke_data_.MiterLimit()));
31   stroke_flags_.setFilterQuality(FilterQualityForPaint(interpolation_quality_));
32   stroke_flags_.setAntiAlias(should_antialias_);
33   fill_flags_.setFilterQuality(FilterQualityForPaint(interpolation_quality_));
34   fill_flags_.setAntiAlias(should_antialias_);
35 }
36 
GraphicsContextState(const GraphicsContextState & other)37 GraphicsContextState::GraphicsContextState(const GraphicsContextState& other)
38     : stroke_flags_(other.stroke_flags_),
39       fill_flags_(other.fill_flags_),
40       stroke_data_(other.stroke_data_),
41       text_drawing_mode_(other.text_drawing_mode_),
42       interpolation_quality_(other.interpolation_quality_),
43       save_count_(0),
44       should_antialias_(other.should_antialias_) {}
45 
Copy(const GraphicsContextState & source)46 void GraphicsContextState::Copy(const GraphicsContextState& source) {
47   this->~GraphicsContextState();
48   new (this) GraphicsContextState(source);
49 }
50 
StrokeFlags(const int stroked_path_length,const int dash_thickness) const51 const PaintFlags& GraphicsContextState::StrokeFlags(
52     const int stroked_path_length,
53     const int dash_thickness) const {
54   stroke_data_.SetupPaintDashPathEffect(&stroke_flags_, stroked_path_length,
55                                         dash_thickness);
56   return stroke_flags_;
57 }
58 
SetStrokeStyle(StrokeStyle style)59 void GraphicsContextState::SetStrokeStyle(StrokeStyle style) {
60   stroke_data_.SetStyle(style);
61 }
62 
SetStrokeThickness(float thickness)63 void GraphicsContextState::SetStrokeThickness(float thickness) {
64   stroke_data_.SetThickness(thickness);
65   stroke_flags_.setStrokeWidth(SkFloatToScalar(thickness));
66 }
67 
SetStrokeColor(const Color & color)68 void GraphicsContextState::SetStrokeColor(const Color& color) {
69   stroke_flags_.setColor(color.Rgb());
70   stroke_flags_.setShader(nullptr);
71 }
72 
SetLineCap(LineCap cap)73 void GraphicsContextState::SetLineCap(LineCap cap) {
74   stroke_data_.SetLineCap(cap);
75   stroke_flags_.setStrokeCap((PaintFlags::Cap)cap);
76 }
77 
SetLineJoin(LineJoin join)78 void GraphicsContextState::SetLineJoin(LineJoin join) {
79   stroke_data_.SetLineJoin(join);
80   stroke_flags_.setStrokeJoin((PaintFlags::Join)join);
81 }
82 
SetMiterLimit(float miter_limit)83 void GraphicsContextState::SetMiterLimit(float miter_limit) {
84   stroke_data_.SetMiterLimit(miter_limit);
85   stroke_flags_.setStrokeMiter(SkFloatToScalar(miter_limit));
86 }
87 
SetFillColor(const Color & color)88 void GraphicsContextState::SetFillColor(const Color& color) {
89   fill_flags_.setColor(color.Rgb());
90   fill_flags_.setShader(nullptr);
91 }
92 
93 // Shadow. (This will need tweaking if we use draw loopers for other things.)
SetDrawLooper(sk_sp<SkDrawLooper> draw_looper)94 void GraphicsContextState::SetDrawLooper(sk_sp<SkDrawLooper> draw_looper) {
95   // Grab a new ref for stroke.
96   stroke_flags_.setLooper(draw_looper);
97   // Pass the existing ref to fill (to minimize refcount churn).
98   fill_flags_.setLooper(std::move(draw_looper));
99 }
100 
SetLineDash(const DashArray & dashes,float dash_offset)101 void GraphicsContextState::SetLineDash(const DashArray& dashes,
102                                        float dash_offset) {
103   stroke_data_.SetLineDash(dashes, dash_offset);
104 }
105 
SetColorFilter(sk_sp<SkColorFilter> color_filter)106 void GraphicsContextState::SetColorFilter(sk_sp<SkColorFilter> color_filter) {
107   // Grab a new ref for stroke.
108   stroke_flags_.setColorFilter(color_filter);
109   // Pass the existing ref to fill (to minimize refcount churn).
110   fill_flags_.setColorFilter(std::move(color_filter));
111 }
112 
SetInterpolationQuality(InterpolationQuality quality)113 void GraphicsContextState::SetInterpolationQuality(
114     InterpolationQuality quality) {
115   interpolation_quality_ = quality;
116   stroke_flags_.setFilterQuality(FilterQualityForPaint(quality));
117   fill_flags_.setFilterQuality(FilterQualityForPaint(quality));
118 }
119 
SetShouldAntialias(bool should_antialias)120 void GraphicsContextState::SetShouldAntialias(bool should_antialias) {
121   should_antialias_ = should_antialias;
122   stroke_flags_.setAntiAlias(should_antialias);
123   fill_flags_.setAntiAlias(should_antialias);
124 }
125 
126 }  // namespace blink
127