blob: ec06efbdc5fc296a620adad6c71ea954262cf969 [file] [log] [blame]
// 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