blob: 237a1a8af61e18a5b7ebb385a9c0dd6ff97ff98e [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 THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_RENDERING_CONTEXT_2D_STATE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_RENDERING_CONTEXT_2D_STATE_H_
#include "base/macros.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/clip_list.h"
#include "third_party/blink/renderer/platform/fonts/font.h"
#include "third_party/blink/renderer/platform/fonts/font_selector_client.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_filter.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_flags.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/skia/include/core/SkRefCnt.h"
namespace blink {
class BaseRenderingContext2D;
class CanvasRenderingContext2D;
class CanvasStyle;
class CSSValue;
class Element;
enum ShadowMode {
kDrawShadowAndForeground,
kDrawShadowOnly,
kDrawForegroundOnly
};
class CanvasRenderingContext2DState final
: public GarbageCollected<CanvasRenderingContext2DState>,
public FontSelectorClient {
public:
enum ClipListCopyMode { kCopyClipList, kDontCopyClipList };
CanvasRenderingContext2DState();
CanvasRenderingContext2DState(const CanvasRenderingContext2DState&,
ClipListCopyMode);
~CanvasRenderingContext2DState() override;
void Trace(Visitor*) const override;
enum PaintType {
kFillPaintType,
kStrokePaintType,
kImagePaintType,
};
// FontSelectorClient implementation
void FontsNeedUpdate(FontSelector*, FontInvalidationReason) 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_; }
void SetTransform(const TransformationMatrix&);
void ResetTransform();
TransformationMatrix GetTransform() const { return transform_; }
AffineTransform GetAffineTransform() const;
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(cc::PaintCanvas* canvas) const {
clip_list_.Playback(canvas);
}
const SkPath& GetCurrentClipPath() const {
return clip_list_.GetCurrentClipPath();
}
void SetFont(const FontDescription&, FontSelector*);
const Font& GetFont() const;
const FontDescription& GetFontDescription() 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(); }
// Prefer to use Style() over StrokeStyle() and FillStyle()
// if properties of CanvasStyle are concerned
CanvasStyle* Style(PaintType) const;
// Check the pattern in StrokeStyle or FillStyle depending on the PaintType
bool HasPattern(PaintType) const;
// Only to be used if the CanvasRenderingContext2DState has Pattern
// Pattern is in either StrokeStyle or FillStyle depending on the PaintType
bool PatternIsAccelerated(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 SetTextLetterSpacing(float letter_space, FontSelector* selector);
float GetTextLetterSpacing() const { return letter_spacing_; }
void SetTextWordSpacing(float word_space, FontSelector* selector);
float GetTextWordSpacing() const { return word_spacing_; }
void SetTextRendering(TextRenderingMode text_rendering,
FontSelector* selector);
TextRenderingMode GetTextRendering() const { return text_rendering_mode_; }
void SetFontKerning(FontDescription::Kerning font_kerning,
FontSelector* selector);
FontDescription::Kerning GetFontKerning() const { return font_kerning_; }
void SetFontStretch(FontSelectionValue font_stretch, FontSelector* selector);
FontSelectionValue GetFontStretch() const { return font_stretch_; }
void SetFontVariantCaps(FontDescription::FontVariantCaps font_kerning,
FontSelector* selector);
FontDescription::FontVariantCaps GetFontVariantCaps() const {
return font_variant_caps_;
}
void SetLineWidth(double line_width) {
stroke_flags_.setStrokeWidth(clampTo<float>(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(clampTo<float>(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:
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_;
TransformationMatrix 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_{kAlphabeticTextBaseline};
Direction direction_{kDirectionInherit};
float letter_spacing_{0};
float word_spacing_{0};
TextRenderingMode text_rendering_mode_{TextRenderingMode::kAutoTextRendering};
FontDescription::Kerning font_kerning_{FontDescription::kAutoKerning};
FontSelectionValue font_stretch_{NormalWidthValue()};
FontDescription::FontVariantCaps font_variant_caps_{
FontDescription::kCapsNormal};
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_;
DISALLOW_COPY_AND_ASSIGN(CanvasRenderingContext2DState);
};
} // namespace blink
#endif