| // Copyright 2015 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. |
| |
| #ifndef CanvasRenderingContext2DState_h |
| #define CanvasRenderingContext2DState_h |
| |
| #include "modules/canvas/canvas2d/ClipList.h" |
| #include "platform/fonts/Font.h" |
| #include "platform/fonts/FontSelectorClient.h" |
| #include "platform/graphics/paint/PaintFilter.h" |
| #include "platform/graphics/paint/PaintFlags.h" |
| #include "platform/transforms/AffineTransform.h" |
| #include "platform/wtf/Vector.h" |
| #include "third_party/skia/include/core/SkRefCnt.h" |
| |
| namespace blink { |
| |
| class BaseRenderingContext2D; |
| class CanvasRenderingContext2D; |
| class CanvasStyle; |
| class CSSValue; |
| class Element; |
| |
| class CanvasRenderingContext2DState final |
| : public GarbageCollectedFinalized<CanvasRenderingContext2DState>, |
| public FontSelectorClient { |
| WTF_MAKE_NONCOPYABLE(CanvasRenderingContext2DState); |
| USING_GARBAGE_COLLECTED_MIXIN(CanvasRenderingContext2DState); |
| |
| public: |
| static CanvasRenderingContext2DState* Create() { |
| return new CanvasRenderingContext2DState; |
| } |
| |
| ~CanvasRenderingContext2DState() override; |
| |
| virtual void Trace(blink::Visitor*); |
| |
| enum ClipListCopyMode { kCopyClipList, kDontCopyClipList }; |
| |
| enum PaintType { |
| kFillPaintType, |
| kStrokePaintType, |
| kImagePaintType, |
| }; |
| |
| static CanvasRenderingContext2DState* Create( |
| const CanvasRenderingContext2DState& other, |
| ClipListCopyMode mode) { |
| return new CanvasRenderingContext2DState(other, mode); |
| } |
| |
| // FontSelectorClient implementation |
| void FontsNeedUpdate(FontSelector*) override; |
| |
| bool HasUnrealizedSaves() const { return unrealized_save_count_; } |
| void Save() { ++unrealized_save_count_; } |
| void Restore() { --unrealized_save_count_; } |
| void ResetUnrealizedSaveCount() { unrealized_save_count_ = 0; } |
| |
| void SetLineDash(const Vector<double>&); |
| const Vector<double>& LineDash() const { return line_dash_; } |
| |
| void SetShouldAntialias(bool); |
| bool ShouldAntialias() const; |
| |
| void SetLineDashOffset(double); |
| double LineDashOffset() const { return line_dash_offset_; } |
| |
| // setTransform returns true iff transform is invertible; |
| void SetTransform(const AffineTransform&); |
| void ResetTransform(); |
| AffineTransform Transform() const { return transform_; } |
| bool IsTransformInvertible() const { return is_transform_invertible_; } |
| |
| void ClipPath(const SkPath&, AntiAliasingMode); |
| bool HasClip() const { return has_clip_; } |
| bool HasComplexClip() const { return has_complex_clip_; } |
| void PlaybackClips(PaintCanvas* canvas) const { clip_list_.Playback(canvas); } |
| const SkPath& GetCurrentClipPath() const { |
| return clip_list_.GetCurrentClipPath(); |
| } |
| |
| void SetFont(const Font&, FontSelector*); |
| const Font& GetFont() const; |
| bool HasRealizedFont() const { return realized_font_; } |
| void SetUnparsedFont(const String& font) { unparsed_font_ = font; } |
| const String& UnparsedFont() const { return unparsed_font_; } |
| |
| void SetFontForFilter(const Font& font) { font_for_filter_ = font; } |
| |
| void SetFilter(const CSSValue*); |
| void SetUnparsedFilter(const String& filter_string) { |
| unparsed_filter_ = filter_string; |
| } |
| const String& UnparsedFilter() const { return unparsed_filter_; } |
| sk_sp<PaintFilter> GetFilter(Element*, |
| IntSize canvas_size, |
| CanvasRenderingContext2D*) const; |
| sk_sp<PaintFilter> GetFilterForOffscreenCanvas(IntSize canvas_size, |
| BaseRenderingContext2D*) const; |
| bool HasFilterForOffscreenCanvas(IntSize canvas_size, |
| BaseRenderingContext2D*) const; |
| bool HasFilter(Element*, |
| IntSize canvas_size, |
| CanvasRenderingContext2D*) const; |
| void ClearResolvedFilter() const; |
| |
| void SetStrokeStyle(CanvasStyle*); |
| CanvasStyle* StrokeStyle() const { return stroke_style_.Get(); } |
| |
| void SetFillStyle(CanvasStyle*); |
| CanvasStyle* FillStyle() const { return fill_style_.Get(); } |
| |
| CanvasStyle* Style(PaintType) const; |
| |
| enum Direction { kDirectionInherit, kDirectionRTL, kDirectionLTR }; |
| |
| void SetDirection(Direction direction) { direction_ = direction; } |
| Direction GetDirection() const { return direction_; } |
| |
| void SetTextAlign(TextAlign align) { text_align_ = align; } |
| TextAlign GetTextAlign() const { return text_align_; } |
| |
| void SetTextBaseline(TextBaseline baseline) { text_baseline_ = baseline; } |
| TextBaseline GetTextBaseline() const { return text_baseline_; } |
| |
| void SetLineWidth(double line_width) { |
| stroke_flags_.setStrokeWidth(line_width); |
| } |
| double LineWidth() const { return stroke_flags_.getStrokeWidth(); } |
| |
| void SetLineCap(LineCap line_cap) { |
| stroke_flags_.setStrokeCap(static_cast<PaintFlags::Cap>(line_cap)); |
| } |
| LineCap GetLineCap() const { |
| return static_cast<LineCap>(stroke_flags_.getStrokeCap()); |
| } |
| |
| void SetLineJoin(LineJoin line_join) { |
| stroke_flags_.setStrokeJoin(static_cast<PaintFlags::Join>(line_join)); |
| } |
| LineJoin GetLineJoin() const { |
| return static_cast<LineJoin>(stroke_flags_.getStrokeJoin()); |
| } |
| |
| void SetMiterLimit(double miter_limit) { |
| stroke_flags_.setStrokeMiter(miter_limit); |
| } |
| double MiterLimit() const { return stroke_flags_.getStrokeMiter(); } |
| |
| void SetShadowOffsetX(double); |
| void SetShadowOffsetY(double); |
| const FloatSize& ShadowOffset() const { return shadow_offset_; } |
| |
| void SetShadowBlur(double); |
| double ShadowBlur() const { return shadow_blur_; } |
| |
| void SetShadowColor(SkColor); |
| SkColor ShadowColor() const { return shadow_color_; } |
| |
| void SetGlobalAlpha(double); |
| double GlobalAlpha() const { return global_alpha_; } |
| |
| void SetGlobalComposite(SkBlendMode); |
| SkBlendMode GlobalComposite() const; |
| |
| void SetImageSmoothingEnabled(bool); |
| bool ImageSmoothingEnabled() const; |
| void SetImageSmoothingQuality(const String&); |
| String ImageSmoothingQuality() const; |
| |
| void SetUnparsedStrokeColor(const String& color) { |
| unparsed_stroke_color_ = color; |
| } |
| const String& UnparsedStrokeColor() const { return unparsed_stroke_color_; } |
| |
| void SetUnparsedFillColor(const String& color) { |
| unparsed_fill_color_ = color; |
| } |
| const String& UnparsedFillColor() const { return unparsed_fill_color_; } |
| |
| bool ShouldDrawShadows() const; |
| |
| enum ImageType { kNoImage, kOpaqueImage, kNonOpaqueImage }; |
| |
| // If paint will not be used for painting a bitmap, set bitmapOpacity to |
| // Opaque. |
| const PaintFlags* GetFlags(PaintType, ShadowMode, ImageType = kNoImage) const; |
| |
| private: |
| CanvasRenderingContext2DState(); |
| CanvasRenderingContext2DState(const CanvasRenderingContext2DState&, |
| ClipListCopyMode); |
| |
| void UpdateLineDash() const; |
| void UpdateStrokeStyle() const; |
| void UpdateFillStyle() const; |
| void UpdateFilterQuality() const; |
| void UpdateFilterQualityWithSkFilterQuality(const SkFilterQuality&) const; |
| void ShadowParameterChanged(); |
| SkDrawLooper* EmptyDrawLooper() const; |
| SkDrawLooper* ShadowOnlyDrawLooper() const; |
| SkDrawLooper* ShadowAndForegroundDrawLooper() const; |
| sk_sp<PaintFilter> ShadowOnlyImageFilter() const; |
| sk_sp<PaintFilter> ShadowAndForegroundImageFilter() const; |
| |
| unsigned unrealized_save_count_; |
| |
| String unparsed_stroke_color_; |
| String unparsed_fill_color_; |
| Member<CanvasStyle> stroke_style_; |
| Member<CanvasStyle> fill_style_; |
| |
| mutable PaintFlags stroke_flags_; |
| mutable PaintFlags fill_flags_; |
| mutable PaintFlags image_flags_; |
| |
| FloatSize shadow_offset_; |
| double shadow_blur_; |
| SkColor shadow_color_; |
| mutable sk_sp<SkDrawLooper> empty_draw_looper_; |
| mutable sk_sp<SkDrawLooper> shadow_only_draw_looper_; |
| mutable sk_sp<SkDrawLooper> shadow_and_foreground_draw_looper_; |
| mutable sk_sp<PaintFilter> shadow_only_image_filter_; |
| mutable sk_sp<PaintFilter> shadow_and_foreground_image_filter_; |
| |
| double global_alpha_; |
| AffineTransform transform_; |
| Vector<double> line_dash_; |
| double line_dash_offset_; |
| |
| String unparsed_font_; |
| Font font_; |
| Font font_for_filter_; |
| |
| String unparsed_filter_; |
| Member<const CSSValue> filter_value_; |
| mutable sk_sp<PaintFilter> resolved_filter_; |
| |
| // Text state. |
| TextAlign text_align_; |
| TextBaseline text_baseline_; |
| Direction direction_; |
| |
| bool realized_font_ : 1; |
| bool is_transform_invertible_ : 1; |
| bool has_clip_ : 1; |
| bool has_complex_clip_ : 1; |
| mutable bool fill_style_dirty_ : 1; |
| mutable bool stroke_style_dirty_ : 1; |
| mutable bool line_dash_dirty_ : 1; |
| |
| bool image_smoothing_enabled_; |
| SkFilterQuality image_smoothing_quality_; |
| |
| ClipList clip_list_; |
| }; |
| |
| } // namespace blink |
| |
| #endif |