| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef FLUTTER_DISPLAY_LIST_DL_PAINT_H_ |
| #define FLUTTER_DISPLAY_LIST_DL_PAINT_H_ |
| |
| #include <memory> |
| #include <utility> |
| #include "flutter/display_list/dl_blend_mode.h" |
| #include "flutter/display_list/dl_color.h" |
| #include "flutter/display_list/effects/dl_color_filter.h" |
| #include "flutter/display_list/effects/dl_color_source.h" |
| #include "flutter/display_list/effects/dl_image_filter.h" |
| #include "flutter/display_list/effects/dl_mask_filter.h" |
| #include "flutter/display_list/effects/dl_path_effect.h" |
| |
| namespace flutter { |
| |
| enum class DlDrawStyle { |
| kFill, //!< fills interior of shapes |
| kStroke, //!< strokes boundary of shapes |
| kStrokeAndFill, //!< both strokes and fills shapes |
| |
| kLastStyle = kStrokeAndFill, |
| kDefaultStyle = kFill, |
| }; |
| |
| enum class DlStrokeCap { |
| kButt, //!< no stroke extension |
| kRound, //!< adds circle |
| kSquare, //!< adds square |
| |
| kLastCap = kSquare, |
| kDefaultCap = kButt, |
| }; |
| |
| enum class DlStrokeJoin { |
| kMiter, //!< extends to miter limit |
| kRound, //!< adds circle |
| kBevel, //!< connects outside edges |
| |
| kLastJoin = kBevel, |
| kDefaultJoin = kMiter, |
| }; |
| |
| class DlPaint { |
| public: |
| static constexpr DlColor kDefaultColor = DlColor::kBlack(); |
| static constexpr float kDefaultWidth = 0.0; |
| static constexpr float kDefaultMiter = 4.0; |
| |
| static const DlPaint kDefault; |
| |
| DlPaint() : DlPaint(DlColor::kBlack()) {} |
| explicit DlPaint(DlColor color); |
| |
| bool isAntiAlias() const { return is_anti_alias_; } |
| DlPaint& setAntiAlias(bool isAntiAlias) { |
| is_anti_alias_ = isAntiAlias; |
| return *this; |
| } |
| |
| bool isInvertColors() const { return is_invert_colors_; } |
| DlPaint& setInvertColors(bool isInvertColors) { |
| is_invert_colors_ = isInvertColors; |
| return *this; |
| } |
| |
| DlColor getColor() const { return color_; } |
| DlPaint& setColor(DlColor color) { |
| color_ = color; |
| return *this; |
| } |
| |
| uint8_t getAlpha() const { return color_.argb() >> 24; } |
| DlPaint& setAlpha(uint8_t alpha) { return setColor(color_.withAlpha(alpha)); } |
| SkScalar getOpacity() const { return color_.getAlphaF(); } |
| DlPaint& setOpacity(SkScalar opacity) { |
| setAlpha(SkScalarRoundToInt(opacity * 0xff)); |
| return *this; |
| } |
| |
| DlBlendMode getBlendMode() const { |
| return static_cast<DlBlendMode>(blend_mode_); |
| } |
| DlPaint& setBlendMode(DlBlendMode mode) { |
| blend_mode_ = static_cast<unsigned>(mode); |
| return *this; |
| } |
| |
| DlDrawStyle getDrawStyle() const { |
| return static_cast<DlDrawStyle>(draw_style_); |
| } |
| DlPaint& setDrawStyle(DlDrawStyle style) { |
| draw_style_ = static_cast<unsigned>(style); |
| return *this; |
| } |
| |
| DlStrokeCap getStrokeCap() const { |
| return static_cast<DlStrokeCap>(stroke_cap_); |
| } |
| DlPaint& setStrokeCap(DlStrokeCap cap) { |
| stroke_cap_ = static_cast<unsigned>(cap); |
| return *this; |
| } |
| |
| DlStrokeJoin getStrokeJoin() const { |
| return static_cast<DlStrokeJoin>(stroke_join_); |
| } |
| DlPaint& setStrokeJoin(DlStrokeJoin join) { |
| stroke_join_ = static_cast<unsigned>(join); |
| return *this; |
| } |
| |
| float getStrokeWidth() const { return stroke_width_; } |
| DlPaint& setStrokeWidth(float width) { |
| stroke_width_ = width; |
| return *this; |
| } |
| |
| float getStrokeMiter() const { return stroke_miter_; } |
| DlPaint& setStrokeMiter(float miter) { |
| stroke_miter_ = miter; |
| return *this; |
| } |
| |
| std::shared_ptr<const DlColorSource> getColorSource() const { |
| return color_source_; |
| } |
| const DlColorSource* getColorSourcePtr() const { return color_source_.get(); } |
| DlPaint& setColorSource(std::shared_ptr<const DlColorSource> source) { |
| color_source_ = std::move(source); |
| return *this; |
| } |
| DlPaint& setColorSource(const DlColorSource* source) { |
| color_source_ = source ? source->shared() : nullptr; |
| return *this; |
| } |
| |
| std::shared_ptr<const DlColorFilter> getColorFilter() const { |
| return color_filter_; |
| } |
| const DlColorFilter* getColorFilterPtr() const { return color_filter_.get(); } |
| DlPaint& setColorFilter(const std::shared_ptr<const DlColorFilter>& filter) { |
| color_filter_ = filter; |
| return *this; |
| } |
| DlPaint& setColorFilter(const DlColorFilter* filter) { |
| color_filter_ = filter ? filter->shared() : nullptr; |
| return *this; |
| } |
| |
| std::shared_ptr<const DlImageFilter> getImageFilter() const { |
| return image_filter_; |
| } |
| const DlImageFilter* getImageFilterPtr() const { return image_filter_.get(); } |
| DlPaint& setImageFilter(const std::shared_ptr<const DlImageFilter>& filter) { |
| image_filter_ = filter; |
| return *this; |
| } |
| DlPaint& setImageFilter(const DlImageFilter* filter) { |
| image_filter_ = filter ? filter->shared() : nullptr; |
| return *this; |
| } |
| |
| std::shared_ptr<const DlMaskFilter> getMaskFilter() const { |
| return mask_filter_; |
| } |
| const DlMaskFilter* getMaskFilterPtr() const { return mask_filter_.get(); } |
| DlPaint& setMaskFilter(const std::shared_ptr<DlMaskFilter>& filter) { |
| mask_filter_ = filter; |
| return *this; |
| } |
| DlPaint& setMaskFilter(const DlMaskFilter* filter) { |
| mask_filter_ = filter ? filter->shared() : nullptr; |
| return *this; |
| } |
| |
| std::shared_ptr<const DlPathEffect> getPathEffect() const { |
| return path_effect_; |
| } |
| const DlPathEffect* getPathEffectPtr() const { return path_effect_.get(); } |
| DlPaint& setPathEffect(const std::shared_ptr<DlPathEffect>& pathEffect) { |
| path_effect_ = pathEffect; |
| return *this; |
| } |
| DlPaint& setPathEffect(const DlPathEffect* effect) { |
| path_effect_ = effect ? effect->shared() : nullptr; |
| return *this; |
| } |
| |
| bool isDefault() const { return *this == kDefault; } |
| |
| bool operator==(DlPaint const& other) const; |
| bool operator!=(DlPaint const& other) const { return !(*this == other); } |
| |
| private: |
| #define ASSERT_ENUM_FITS(last_enum, num_bits) \ |
| static_assert(static_cast<int>(last_enum) < (1 << num_bits) && \ |
| static_cast<int>(last_enum) * 2 >= (1 << num_bits)) |
| |
| static constexpr int kBlendModeBits = 5; |
| static constexpr int kDrawStyleBits = 2; |
| static constexpr int kStrokeCapBits = 2; |
| static constexpr int kStrokeJoinBits = 2; |
| ASSERT_ENUM_FITS(DlBlendMode::kLastMode, kBlendModeBits); |
| ASSERT_ENUM_FITS(DlDrawStyle::kLastStyle, kDrawStyleBits); |
| ASSERT_ENUM_FITS(DlStrokeCap::kLastCap, kStrokeCapBits); |
| ASSERT_ENUM_FITS(DlStrokeJoin::kLastJoin, kStrokeJoinBits); |
| |
| union { |
| struct { |
| unsigned blend_mode_ : kBlendModeBits; |
| unsigned draw_style_ : kDrawStyleBits; |
| unsigned stroke_cap_ : kStrokeCapBits; |
| unsigned stroke_join_ : kStrokeJoinBits; |
| unsigned is_anti_alias_ : 1; |
| unsigned is_invert_colors_ : 1; |
| }; |
| }; |
| |
| DlColor color_; |
| float stroke_width_; |
| float stroke_miter_; |
| |
| std::shared_ptr<const DlColorSource> color_source_; |
| std::shared_ptr<const DlColorFilter> color_filter_; |
| std::shared_ptr<const DlImageFilter> image_filter_; |
| std::shared_ptr<const DlMaskFilter> mask_filter_; |
| std::shared_ptr<const DlPathEffect> path_effect_; |
| }; |
| |
| } // namespace flutter |
| |
| #endif // FLUTTER_DISPLAY_LIST_DL_PAINT_H_ |