Commit afb269d4 authored by Emil A Eklund's avatar Emil A Eklund Committed by Commit Bot

Clean up BoxPainterBase

Refactor and clean up BoxPainterBase to improve legibility and to reduce
code duplication.

Bug: 714962
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: Ib738b19e62117046391a9c7b45dcddd1c2ecbb23
Reviewed-on: https://chromium-review.googlesource.com/1060568Reviewed-by: default avatarStefan Zager <szager@chromium.org>
Commit-Queue: Emil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#558910}
parent 5ab0c625
......@@ -269,47 +269,6 @@ bool BoxPainterBase::CalculateFillLayerOcclusionCulling(
return is_non_associative;
}
FloatRoundedRect BoxPainterBase::BackgroundRoundedRectAdjustedForBleedAvoidance(
const LayoutRect& border_rect,
bool flow_box_has_multiple_fragments,
const LayoutSize& flow_box_size,
bool include_logical_left_edge,
bool include_logical_right_edge,
FloatRoundedRect background_rounded_rect) const {
// Inset the background rect by a "safe" amount: 1/2 border-width for opaque
// border styles, 1/6 border-width for double borders.
// TODO(fmalita): we should be able to fold these parameters into
// BoxBorderInfo or BoxDecorationData and avoid calling getBorderEdgeInfo
// redundantly here.
BorderEdge edges[4];
style_.GetBorderEdgeInfo(edges, include_logical_left_edge,
include_logical_right_edge);
// Use the most conservative inset to avoid mixed-style corner issues.
float fractional_inset = 1.0f / 2;
for (auto& edge : edges) {
if (edge.BorderStyle() == EBorderStyle::kDouble) {
fractional_inset = 1.0f / 6;
break;
}
}
FloatRectOutsets insets(
-fractional_inset * edges[static_cast<unsigned>(BoxSide::kTop)].Width(),
-fractional_inset * edges[static_cast<unsigned>(BoxSide::kRight)].Width(),
-fractional_inset *
edges[static_cast<unsigned>(BoxSide::kBottom)].Width(),
-fractional_inset * edges[static_cast<unsigned>(BoxSide::kLeft)].Width());
FloatRect inset_rect(background_rounded_rect.Rect());
inset_rect.Expand(insets);
FloatRoundedRect::Radii inset_radii(background_rounded_rect.GetRadii());
inset_radii.Shrink(-insets.Top(), -insets.Bottom(), -insets.Left(),
-insets.Right());
return FloatRoundedRect(inset_rect, inset_radii);
}
BoxPainterBase::FillLayerInfo::FillLayerInfo(
const Document& doc,
const ComputedStyle& style,
......@@ -449,16 +408,94 @@ inline bool PaintFastBottomLayer(const DisplayItemClient& image_client,
return true;
}
// Inset the background rect by a "safe" amount: 1/2 border-width for opaque
// border styles, 1/6 border-width for double borders.
FloatRoundedRect BackgroundRoundedRectAdjustedForBleedAvoidance(
const ComputedStyle& style,
const LayoutRect& border_rect,
bool flow_box_has_multiple_fragments,
bool include_logical_left_edge,
bool include_logical_right_edge,
FloatRoundedRect background_rounded_rect) {
// TODO(fmalita): we should be able to fold these parameters into
// BoxBorderInfo or BoxDecorationData and avoid calling getBorderEdgeInfo
// redundantly here.
BorderEdge edges[4];
style.GetBorderEdgeInfo(edges, include_logical_left_edge,
include_logical_right_edge);
} // anonymous namespace
// Use the most conservative inset to avoid mixed-style corner issues.
float fractional_inset = 1.0f / 2;
for (auto& edge : edges) {
if (edge.BorderStyle() == EBorderStyle::kDouble) {
fractional_inset = 1.0f / 6;
break;
}
}
void BoxPainterBase::PaintFillLayerBackground(
GraphicsContext& context,
const FillLayerInfo& info,
Image* image,
SkBlendMode composite_op,
const BackgroundImageGeometry& geometry,
LayoutRect scrolled_paint_rect) {
FloatRectOutsets insets(
-fractional_inset * edges[static_cast<unsigned>(BoxSide::kTop)].Width(),
-fractional_inset * edges[static_cast<unsigned>(BoxSide::kRight)].Width(),
-fractional_inset *
edges[static_cast<unsigned>(BoxSide::kBottom)].Width(),
-fractional_inset * edges[static_cast<unsigned>(BoxSide::kLeft)].Width());
FloatRect inset_rect(background_rounded_rect.Rect());
inset_rect.Expand(insets);
FloatRoundedRect::Radii inset_radii(background_rounded_rect.GetRadii());
inset_radii.Shrink(-insets.Top(), -insets.Bottom(), -insets.Left(),
-insets.Right());
return FloatRoundedRect(inset_rect, inset_radii);
}
FloatRoundedRect RoundedBorderRectForClip(
const ComputedStyle& style,
const BoxPainterBase::FillLayerInfo& info,
const FillLayer& bg_layer,
const LayoutRect& rect,
bool flow_box_has_multiple_fragments,
const LayoutSize& flow_box_size,
BackgroundBleedAvoidance bleed_avoidance,
LayoutRectOutsets border_padding_insets) {
if (!info.is_rounded_fill)
return FloatRoundedRect();
FloatRoundedRect border = style.GetRoundedBorderFor(
rect, info.include_left_edge, info.include_right_edge);
if (flow_box_has_multiple_fragments) {
FloatRoundedRect segment_border = style.GetRoundedBorderFor(
LayoutRect(LayoutPoint(), LayoutSize(FlooredIntSize(flow_box_size))),
info.include_left_edge, info.include_right_edge);
border.SetRadii(segment_border.GetRadii());
}
if (info.is_border_fill &&
bleed_avoidance == kBackgroundBleedShrinkBackground) {
border = BackgroundRoundedRectAdjustedForBleedAvoidance(
style, rect, flow_box_has_multiple_fragments, info.include_left_edge,
info.include_right_edge, border);
}
// Clip to the padding or content boxes as necessary.
if (bg_layer.Clip() == EFillBox::kContent) {
border = style.GetRoundedInnerBorderFor(
LayoutRect(border.Rect()), border_padding_insets,
info.include_left_edge, info.include_right_edge);
} else if (bg_layer.Clip() == EFillBox::kPadding) {
border = style.GetRoundedInnerBorderFor(LayoutRect(border.Rect()),
info.include_left_edge,
info.include_right_edge);
}
return border;
}
void PaintFillLayerBackground(GraphicsContext& context,
const BoxPainterBase::FillLayerInfo& info,
Node* node,
Image* image,
SkBlendMode composite_op,
const BackgroundImageGeometry& geometry,
LayoutRect scrolled_paint_rect) {
// Paint the color first underneath all images, culled if background image
// occludes it.
// TODO(trchen): In the !bgLayer.hasRepeatXY() case, we could improve the
......@@ -475,7 +512,7 @@ void BoxPainterBase::PaintFillLayerBackground(
if (info.should_paint_image && !geometry.DestRect().IsEmpty() && image) {
TRACE_EVENT1(
TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data",
InspectorPaintImageEvent::Data(node_, *info.image, image->Rect(),
InspectorPaintImageEvent::Data(node, *info.image, image->Rect(),
FloatRect(scrolled_paint_rect)));
context.DrawTiledImage(image, FloatRect(geometry.DestRect()),
FloatPoint(geometry.Phase()),
......@@ -484,41 +521,22 @@ void BoxPainterBase::PaintFillLayerBackground(
}
}
LayoutRectOutsets BoxPainterBase::BorderOutsets(
const FillLayerInfo& info) const {
LayoutRectOutsets borders = border_;
LayoutRectOutsets AdjustOutsetsForEdgeInclusion(
const LayoutRectOutsets outsets,
const BoxPainterBase::FillLayerInfo& info) {
LayoutRectOutsets adjusted = outsets;
if (!info.include_right_edge)
borders.SetRight(LayoutUnit());
adjusted.SetRight(LayoutUnit());
if (!info.include_left_edge)
borders.SetLeft(LayoutUnit());
return borders;
adjusted.SetLeft(LayoutUnit());
return adjusted;
}
LayoutRectOutsets BoxPainterBase::PaddingOutsets(
const FillLayerInfo& info) const {
LayoutRectOutsets paddings = padding_;
if (!info.include_right_edge)
paddings.SetRight(LayoutUnit());
if (!info.include_left_edge)
paddings.SetLeft(LayoutUnit());
return paddings;
}
} // anonymous namespace
FloatRoundedRect BoxPainterBase::GetBackgroundRoundedRect(
const LayoutRect& border_rect,
bool flow_box_has_multiple_fragments,
const LayoutSize& flow_box_size,
bool include_logical_left_edge,
bool include_logical_right_edge) const {
FloatRoundedRect border = style_.GetRoundedBorderFor(
border_rect, include_logical_left_edge, include_logical_right_edge);
if (flow_box_has_multiple_fragments) {
FloatRoundedRect segment_border = style_.GetRoundedBorderFor(
LayoutRect(LayoutPoint(), LayoutSize(FlooredIntSize(flow_box_size))),
include_logical_left_edge, include_logical_right_edge);
border.SetRadii(segment_border.GetRadii());
}
return border;
LayoutRectOutsets BoxPainterBase::BorderOutsets(
const FillLayerInfo& info) const {
return AdjustOutsetsForEdgeInclusion(border_, info);
}
void BoxPainterBase::PaintFillLayer(const PaintInfo& paint_info,
......@@ -568,8 +586,8 @@ void BoxPainterBase::PaintFillLayer(const PaintInfo& paint_info,
LayoutRectOutsets border_padding_insets = -(border_ + padding_);
FloatRoundedRect border_rect = RoundedBorderRectForClip(
info, bg_layer, rect, flow_box_has_multiple_fragments, flow_box_size,
bleed_avoidance, border_padding_insets);
style_, info, bg_layer, rect, flow_box_has_multiple_fragments,
flow_box_size, bleed_avoidance, border_padding_insets);
// Fast path for drawing simple color backgrounds.
if (PaintFastBottomLayer(display_item_, node_, paint_info, info, rect,
......@@ -598,9 +616,9 @@ void BoxPainterBase::PaintFillLayer(const PaintInfo& paint_info,
// Clip to the padding or content boxes as necessary.
LayoutRect clip_rect = scrolled_paint_rect;
clip_rect.Contract(BorderOutsets(info));
clip_rect.Contract(AdjustOutsetsForEdgeInclusion(border_, info));
if (bg_layer.Clip() == EFillBox::kContent)
clip_rect.Contract(PaddingOutsets(info));
clip_rect.Contract(AdjustOutsetsForEdgeInclusion(padding_, info));
background_clip_state_saver.Save();
// TODO(chrishtr): this should be pixel-snapped.
context.Clip(FloatRect(clip_rect));
......@@ -614,8 +632,8 @@ void BoxPainterBase::PaintFillLayer(const PaintInfo& paint_info,
break;
}
PaintFillLayerBackground(context, info, image.get(), composite_op, geometry,
scrolled_paint_rect);
PaintFillLayerBackground(context, info, node_, image.get(), composite_op,
geometry, scrolled_paint_rect);
}
void BoxPainterBase::PaintFillLayerTextFillBox(
......@@ -639,7 +657,7 @@ void BoxPainterBase::PaintFillLayerTextFillBox(
context.Clip(mask_rect);
context.BeginLayer(1, composite_op);
PaintFillLayerBackground(context, info, image, SkBlendMode::kSrcOver,
PaintFillLayerBackground(context, info, node_, image, SkBlendMode::kSrcOver,
geometry, scrolled_paint_rect);
// Create the text mask layer and draw the text into the mask. We do this by
......@@ -654,41 +672,6 @@ void BoxPainterBase::PaintFillLayerTextFillBox(
context.EndLayer(); // Background layer.
}
FloatRoundedRect BoxPainterBase::RoundedBorderRectForClip(
const BoxPainterBase::FillLayerInfo& info,
const FillLayer& bg_layer,
const LayoutRect& rect,
bool flow_box_has_multiple_fragments,
const LayoutSize& flow_box_size,
BackgroundBleedAvoidance bleed_avoidance,
LayoutRectOutsets border_padding_insets) const {
if (!info.is_rounded_fill)
return FloatRoundedRect();
FloatRoundedRect border = GetBackgroundRoundedRect(
rect, flow_box_has_multiple_fragments, flow_box_size,
info.include_left_edge, info.include_right_edge);
if (info.is_border_fill &&
bleed_avoidance == kBackgroundBleedShrinkBackground) {
border = BackgroundRoundedRectAdjustedForBleedAvoidance(
rect, flow_box_has_multiple_fragments, flow_box_size,
info.include_left_edge, info.include_right_edge, border);
}
// Clip to the padding or content boxes as necessary.
if (bg_layer.Clip() == EFillBox::kContent) {
border = style_.GetRoundedInnerBorderFor(
LayoutRect(border.Rect()), border_padding_insets,
info.include_left_edge, info.include_right_edge);
} else if (bg_layer.Clip() == EFillBox::kPadding) {
border = style_.GetRoundedInnerBorderFor(LayoutRect(border.Rect()),
info.include_left_edge,
info.include_right_edge);
}
return border;
}
void BoxPainterBase::PaintBorder(const ImageResourceObserver& obj,
const Document& document,
Node* node,
......@@ -733,7 +716,6 @@ void BoxPainterBase::PaintMaskImages(const PaintInfo& paint_info,
// prevent a flash of unmasked content.
if (mask_box_image)
all_mask_images_loaded &= mask_box_image->IsLoaded();
all_mask_images_loaded &= mask_layers.ImagesAreLoaded();
paint_info.context.BeginLayer(1, SkBlendMode::kDstIn);
......
......@@ -143,31 +143,7 @@ class BoxPainterBase {
};
protected:
FloatRoundedRect BackgroundRoundedRectAdjustedForBleedAvoidance(
const LayoutRect& border_rect,
bool flow_box_has_multiple_fragments,
const LayoutSize& flow_box_size,
bool include_logical_left_edge,
bool include_logical_right_edge,
FloatRoundedRect background_rounded_rect) const;
FloatRoundedRect RoundedBorderRectForClip(
const FillLayerInfo&,
const FillLayer&,
const LayoutRect&,
bool flow_box_has_multiple_fragments,
const LayoutSize& flow_box_size,
BackgroundBleedAvoidance,
LayoutRectOutsets border_padding_insets) const;
void PaintFillLayerBackground(GraphicsContext&,
const FillLayerInfo&,
Image*,
SkBlendMode,
const BackgroundImageGeometry&,
LayoutRect scrolled_paint_rect);
LayoutRectOutsets BorderOutsets(const FillLayerInfo&) const;
LayoutRectOutsets PaddingOutsets(const FillLayerInfo&) const;
void PaintFillLayerTextFillBox(GraphicsContext&,
const FillLayerInfo&,
Image*,
......@@ -186,13 +162,6 @@ class BoxPainterBase {
virtual FillLayerInfo GetFillLayerInfo(const Color&,
const FillLayer&,
BackgroundBleedAvoidance) const = 0;
FloatRoundedRect GetBackgroundRoundedRect(
const LayoutRect& border_rect,
bool flow_box_has_multiple_fragments,
const LayoutSize& flow_box_size,
bool include_logical_left_edge,
bool include_logical_right_edge) const;
static void PaintInsetBoxShadow(const PaintInfo&,
const FloatRoundedRect&,
const ComputedStyle&,
......@@ -204,8 +173,8 @@ class BoxPainterBase {
Member<const Document> document_;
const ComputedStyle& style_;
Member<Node> node_;
LayoutRectOutsets border_;
LayoutRectOutsets padding_;
const LayoutRectOutsets border_;
const LayoutRectOutsets padding_;
const PaintLayer* paint_layer_;
};
......
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