Commit 0833a75e authored by Fredrik Söderqvist's avatar Fredrik Söderqvist Committed by Chromium LUCI CQ

Move GraphicsContext::DrawInnerShadow to BoxPainterBase

Move said method, mostly verbatim, to BoxPainterBase, inlining it in
BoxPainterBase::PaintInsetBoxShadow.

The side clipping setup is merged with the actual computation, and thus
work directly with the |sides_to_include| parameter.

The "hole" naming is replaced with "inner" to better match spec terms.

Bug: 1159514
Change-Id: I09168a527b0978c717160b325c16d5e090be5192
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2620802Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#842054}
parent 8cb5b4bd
...@@ -182,42 +182,95 @@ void BoxPainterBase::PaintInsetBoxShadowWithInnerRect( ...@@ -182,42 +182,95 @@ void BoxPainterBase::PaintInsetBoxShadowWithInnerRect(
PaintInsetBoxShadow(info, bounds, style); PaintInsetBoxShadow(info, bounds, style);
} }
namespace {
inline FloatRect AreaCastingShadowInHole(const FloatRect& hole_rect,
const ShadowData& shadow) {
FloatRect bounds(hole_rect);
bounds.Inflate(shadow.Blur());
if (shadow.Spread() < 0)
bounds.Inflate(-shadow.Spread());
FloatRect offset_bounds = bounds;
offset_bounds.MoveBy(-shadow.Location());
return UnionRect(bounds, offset_bounds);
}
void AdjustInnerRectForSideClipping(FloatRect& inner_rect,
const ShadowData& shadow,
PhysicalBoxSides sides_to_include) {
if (!sides_to_include.left) {
float extend_by = std::max(shadow.X(), 0.0f) + shadow.Blur();
inner_rect.Move(-extend_by, 0);
inner_rect.SetWidth(inner_rect.Width() + extend_by);
}
if (!sides_to_include.top) {
float extend_by = std::max(shadow.Y(), 0.0f) + shadow.Blur();
inner_rect.Move(0, -extend_by);
inner_rect.SetHeight(inner_rect.Height() + extend_by);
}
if (!sides_to_include.right) {
float shrink_by = std::min(shadow.X(), 0.0f) - shadow.Blur();
inner_rect.SetWidth(inner_rect.Width() - shrink_by);
}
if (!sides_to_include.bottom) {
float shrink_by = std::min(shadow.Y(), 0.0f) - shadow.Blur();
inner_rect.SetHeight(inner_rect.Height() - shrink_by);
}
}
} // namespace
void BoxPainterBase::PaintInsetBoxShadow(const PaintInfo& info, void BoxPainterBase::PaintInsetBoxShadow(const PaintInfo& info,
const FloatRoundedRect& bounds, const FloatRoundedRect& bounds,
const ComputedStyle& style, const ComputedStyle& style,
PhysicalBoxSides sides_to_include) { PhysicalBoxSides sides_to_include) {
GraphicsContext& context = info.context; GraphicsContext& context = info.context;
GraphicsContextStateSaver state_saver(context, false);
const ShadowList* shadow_list = style.BoxShadow(); const ShadowList* shadow_list = style.BoxShadow();
for (wtf_size_t i = shadow_list->Shadows().size(); i--;) { for (wtf_size_t i = shadow_list->Shadows().size(); i--;) {
const ShadowData& shadow = shadow_list->Shadows()[i]; const ShadowData& shadow = shadow_list->Shadows()[i];
if (shadow.Style() != ShadowStyle::kInset) if (shadow.Style() != ShadowStyle::kInset)
continue; continue;
if (!shadow.X() && !shadow.Y() && !shadow.Blur() && !shadow.Spread())
FloatSize shadow_offset(shadow.X(), shadow.Y());
float shadow_blur = shadow.Blur();
float shadow_spread = shadow.Spread();
if (shadow_offset.IsZero() && !shadow_blur && !shadow_spread)
continue; continue;
const Color& shadow_color = shadow.GetColor().Resolve( const Color& shadow_color = shadow.GetColor().Resolve(
style.VisitedDependentColor(GetCSSPropertyColor()), style.VisitedDependentColor(GetCSSPropertyColor()),
style.UsedColorScheme()); style.UsedColorScheme());
// The inset shadow case. FloatRect inner_rect(bounds.Rect());
GraphicsContext::Edges clipped_edges = GraphicsContext::kNoEdge; inner_rect.Inflate(-shadow.Spread());
if (!sides_to_include.top) if (inner_rect.IsEmpty()) {
clipped_edges |= GraphicsContext::kTopEdge; context.FillRoundedRect(bounds, shadow_color);
if (!sides_to_include.right) continue;
clipped_edges |= GraphicsContext::kRightEdge; }
if (!sides_to_include.bottom) AdjustInnerRectForSideClipping(inner_rect, shadow, sides_to_include);
clipped_edges |= GraphicsContext::kBottomEdge;
if (!sides_to_include.left) FloatRoundedRect inner_rounded_rect(inner_rect, bounds.GetRadii());
clipped_edges |= GraphicsContext::kLeftEdge; GraphicsContextStateSaver state_saver(context);
context.DrawInnerShadow(bounds, shadow_color, shadow_offset, shadow_blur, if (bounds.IsRounded()) {
shadow_spread, clipped_edges); context.ClipRoundedRect(bounds);
if (shadow.Spread() < 0)
inner_rounded_rect.ExpandRadii(-shadow.Spread());
else
inner_rounded_rect.ShrinkRadii(shadow.Spread());
} else {
context.Clip(bounds.Rect());
}
DrawLooperBuilder draw_looper_builder;
draw_looper_builder.AddShadow(ToFloatSize(shadow.Location()), shadow.Blur(),
shadow_color,
DrawLooperBuilder::kShadowRespectsTransforms,
DrawLooperBuilder::kShadowIgnoresAlpha);
context.SetDrawLooper(draw_looper_builder.DetachDrawLooper());
Color fill_color(shadow_color.Red(), shadow_color.Green(),
shadow_color.Blue());
FloatRect outer_rect = AreaCastingShadowInHole(bounds.Rect(), shadow);
context.FillRectWithRoundedHole(outer_rect, inner_rounded_rect, fill_color);
} }
} }
......
...@@ -486,91 +486,6 @@ void GraphicsContext::DrawFocusRing(const Vector<IntRect>& rects, ...@@ -486,91 +486,6 @@ void GraphicsContext::DrawFocusRing(const Vector<IntRect>& rects,
} }
} }
static inline FloatRect AreaCastingShadowInHole(
const FloatRect& hole_rect,
float shadow_blur,
float shadow_spread,
const FloatSize& shadow_offset) {
FloatRect bounds(hole_rect);
bounds.Inflate(shadow_blur);
if (shadow_spread < 0)
bounds.Inflate(-shadow_spread);
FloatRect offset_bounds = bounds;
offset_bounds.Move(-shadow_offset);
return UnionRect(bounds, offset_bounds);
}
static void AdjustHoleForSideClipping(FloatRect& hole_rect,
const FloatSize& shadow_offset,
float shadow_blur,
GraphicsContext::Edges clipped_edges) {
if (clipped_edges & GraphicsContext::kLeftEdge) {
float extend_by = std::max(shadow_offset.Width(), 0.0f) + shadow_blur;
hole_rect.Move(-extend_by, 0);
hole_rect.SetWidth(hole_rect.Width() + extend_by);
}
if (clipped_edges & GraphicsContext::kTopEdge) {
float extend_by = std::max(shadow_offset.Height(), 0.0f) + shadow_blur;
hole_rect.Move(0, -extend_by);
hole_rect.SetHeight(hole_rect.Height() + extend_by);
}
if (clipped_edges & GraphicsContext::kRightEdge) {
float shrink_by = std::min(shadow_offset.Width(), 0.0f) - shadow_blur;
hole_rect.SetWidth(hole_rect.Width() - shrink_by);
}
if (clipped_edges & GraphicsContext::kBottomEdge) {
float shrink_by = std::min(shadow_offset.Height(), 0.0f) - shadow_blur;
hole_rect.SetHeight(hole_rect.Height() - shrink_by);
}
}
void GraphicsContext::DrawInnerShadow(const FloatRoundedRect& rect,
const Color& orig_shadow_color,
const FloatSize& shadow_offset,
float shadow_blur,
float shadow_spread,
Edges clipped_edges) {
SkColor shadow_color = DarkModeFilterHelper::ApplyToColorIfNeeded(
this, orig_shadow_color.Rgb(), DarkModeFilter::ElementRole::kBackground);
FloatRect hole_rect(rect.Rect());
hole_rect.Inflate(-shadow_spread);
if (hole_rect.IsEmpty()) {
FillRoundedRect(rect, Color(shadow_color));
return;
}
AdjustHoleForSideClipping(hole_rect, shadow_offset, shadow_blur,
clipped_edges);
FloatRoundedRect rounded_hole(hole_rect, rect.GetRadii());
GraphicsContextStateSaver state_saver(*this);
if (rect.IsRounded()) {
ClipRoundedRect(rect);
if (shadow_spread < 0)
rounded_hole.ExpandRadii(-shadow_spread);
else
rounded_hole.ShrinkRadii(shadow_spread);
} else {
Clip(rect.Rect());
}
DrawLooperBuilder draw_looper_builder;
draw_looper_builder.AddShadow(shadow_offset, shadow_blur, shadow_color,
DrawLooperBuilder::kShadowRespectsTransforms,
DrawLooperBuilder::kShadowIgnoresAlpha);
SetDrawLooper(draw_looper_builder.DetachDrawLooper());
Color fill_color(SkColorGetR(shadow_color), SkColorGetG(shadow_color),
SkColorGetB(shadow_color));
FloatRect outer_rect = AreaCastingShadowInHole(rect.Rect(), shadow_blur,
shadow_spread, shadow_offset);
FillRectWithRoundedHole(outer_rect, rounded_hole, fill_color);
}
static void EnforceDotsAtEndpoints(GraphicsContext& context, static void EnforceDotsAtEndpoints(GraphicsContext& context,
FloatPoint& p1, FloatPoint& p1,
FloatPoint& p2, FloatPoint& p2,
...@@ -1161,6 +1076,16 @@ void GraphicsContext::FillDRRect(const FloatRoundedRect& outer, ...@@ -1161,6 +1076,16 @@ void GraphicsContext::FillDRRect(const FloatRoundedRect& outer,
canvas_->drawRRect(stroke_r_rect, stroke_flags); canvas_->drawRRect(stroke_r_rect, stroke_flags);
} }
void GraphicsContext::FillRectWithRoundedHole(
const FloatRect& rect,
const FloatRoundedRect& rounded_hole_rect,
const Color& color) {
PaintFlags flags(ImmutableState()->FillFlags());
flags.setColor(DarkModeFilterHelper::ApplyToColorIfNeeded(
this, color.Rgb(), DarkModeFilter::ElementRole::kBackground));
canvas_->drawDRRect(SkRRect::MakeRect(rect), rounded_hole_rect, flags);
}
void GraphicsContext::FillEllipse(const FloatRect& ellipse) { void GraphicsContext::FillEllipse(const FloatRect& ellipse) {
DrawOval(ellipse, ImmutableState()->FillFlags()); DrawOval(ellipse, ImmutableState()->FillFlags());
} }
...@@ -1304,16 +1229,6 @@ void GraphicsContext::ConcatCTM(const AffineTransform& affine) { ...@@ -1304,16 +1229,6 @@ void GraphicsContext::ConcatCTM(const AffineTransform& affine) {
Concat(AffineTransformToSkMatrix(affine)); Concat(AffineTransformToSkMatrix(affine));
} }
void GraphicsContext::FillRectWithRoundedHole(
const FloatRect& rect,
const FloatRoundedRect& rounded_hole_rect,
const Color& color) {
PaintFlags flags(ImmutableState()->FillFlags());
flags.setColor(DarkModeFilterHelper::ApplyToColorIfNeeded(
this, color.Rgb(), DarkModeFilter::ElementRole::kBackground));
canvas_->drawDRRect(SkRRect::MakeRect(rect), rounded_hole_rect, flags);
}
void GraphicsContext::AdjustLineToPixelBoundaries(FloatPoint& p1, void GraphicsContext::AdjustLineToPixelBoundaries(FloatPoint& p1,
FloatPoint& p2, FloatPoint& p2,
float stroke_width) { float stroke_width) {
......
...@@ -215,6 +215,9 @@ class PLATFORM_EXPORT GraphicsContext { ...@@ -215,6 +215,9 @@ class PLATFORM_EXPORT GraphicsContext {
void FillDRRect(const FloatRoundedRect&, void FillDRRect(const FloatRoundedRect&,
const FloatRoundedRect&, const FloatRoundedRect&,
const Color&); const Color&);
void FillRectWithRoundedHole(const FloatRect&,
const FloatRoundedRect& rounded_hole_rect,
const Color&);
void StrokeRect(const FloatRect&, float line_width); void StrokeRect(const FloatRect&, float line_width);
...@@ -365,21 +368,6 @@ class PLATFORM_EXPORT GraphicsContext { ...@@ -365,21 +368,6 @@ class PLATFORM_EXPORT GraphicsContext {
ColorScheme color_scheme); ColorScheme color_scheme);
void DrawFocusRing(const Path&, float width, int offset, const Color&); void DrawFocusRing(const Path&, float width, int offset, const Color&);
enum Edge {
kNoEdge = 0,
kTopEdge = 1 << 1,
kRightEdge = 1 << 2,
kBottomEdge = 1 << 3,
kLeftEdge = 1 << 4
};
typedef unsigned Edges;
void DrawInnerShadow(const FloatRoundedRect&,
const Color& shadow_color,
const FloatSize& shadow_offset,
float shadow_blur,
float shadow_spread,
Edges clipped_edges = kNoEdge);
const PaintFlags& FillFlags() const { return ImmutableState()->FillFlags(); } const PaintFlags& FillFlags() const { return ImmutableState()->FillFlags(); }
// If the length of the path to be stroked is known, pass it in for correct // If the length of the path to be stroked is known, pass it in for correct
// dash or dot placement. Border painting uses a stroke thickness determined // dash or dot placement. Border painting uses a stroke thickness determined
...@@ -505,10 +493,6 @@ class PLATFORM_EXPORT GraphicsContext { ...@@ -505,10 +493,6 @@ class PLATFORM_EXPORT GraphicsContext {
} }
} }
void FillRectWithRoundedHole(const FloatRect&,
const FloatRoundedRect& rounded_hole_rect,
const Color&);
class DarkModeFlags; class DarkModeFlags;
// This is owned by paint_recorder_. Never delete this object. // This is owned by paint_recorder_. Never delete this object.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment