Commit 3cd56097 authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

Support non-zero paint offset for scroll bars

The previous code supposed that we created PaintOffsetTranslation for
all scrollable elements. This is not true for SVG foreign objects for
which we can't create PaintOffsetTranslation because the offset is in
SVG space which is affected by transform.

Bug: 1030109
Change-Id: I161821c50e091257f77b2f806ac5c00c903198da
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2012904Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#733895}
parent 7d75ae11
......@@ -2189,12 +2189,12 @@ void CompositedLayerMapping::PaintScrollableArea(
if (graphics_layer == LayerForHorizontalScrollbar()) {
if (const Scrollbar* scrollbar = scrollable_area->HorizontalScrollbar()) {
if (cull_rect.Intersects(scrollbar->FrameRect()))
scrollbar->Paint(context);
scrollbar->Paint(context, IntPoint());
}
} else if (graphics_layer == LayerForVerticalScrollbar()) {
if (const Scrollbar* scrollbar = scrollable_area->VerticalScrollbar()) {
if (cull_rect.Intersects(scrollbar->FrameRect()))
scrollbar->Paint(context);
scrollbar->Paint(context, IntPoint());
}
} else if (graphics_layer == LayerForScrollCorner()) {
ScrollableAreaPainter painter(*scrollable_area);
......
......@@ -2878,8 +2878,13 @@ static IntRect InvalidatePaintOfScrollbarIfNeeded(
bool is_overlay = scrollbar && scrollbar->IsOverlayScrollbar();
IntRect new_visual_rect;
if (scrollbar)
if (scrollbar) {
new_visual_rect = scrollbar->FrameRect();
// TODO(crbug.com/1020913): We should not round paint_offset but should
// consider subpixel accumulation when painting scrollbars.
new_visual_rect.MoveBy(
RoundedIntPoint(context.fragment_data->PaintOffset()));
}
if (needs_paint_invalidation && graphics_layer) {
// If the scrollbar needs paint invalidation but didn't change location/size
......@@ -2952,8 +2957,10 @@ void PaintLayerScrollableArea::InvalidatePaintOfScrollControlsIfNeeded(
box_geometry_has_been_invalidated, context));
IntRect scroll_corner_and_resizer_visual_rect = ScrollCornerAndResizerRect();
// TODO(crbug.com/1020913): We should not round paint_offset but should
// consider subpixel accumulation when painting scrollbars.
scroll_corner_and_resizer_visual_rect.MoveBy(
RoundedIntPoint(box.FirstFragment().PaintOffset()));
RoundedIntPoint(context.fragment_data->PaintOffset()));
if (ScrollControlNeedsPaintInvalidation(
scroll_corner_and_resizer_visual_rect,
scroll_corner_and_resizer_visual_rect_,
......
......@@ -201,18 +201,16 @@ void ScrollableAreaPainter::PaintScrollbar(GraphicsContext& context,
Scrollbar& scrollbar,
const CullRect& cull_rect,
const IntPoint& paint_offset) {
// We create PaintOffsetTranslation for scrollable area, so the rounded
// paint offset is always zero.
// TODO(crbug.com/1020913): We should not round paint_offset but should
// consider subpixel accumulation when painting scrollbars.
DCHECK_EQ(paint_offset, IntPoint());
IntRect rect = scrollbar.FrameRect();
rect.MoveBy(paint_offset);
if (!cull_rect.Intersects(rect))
return;
if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
scrollbar.IsCustomScrollbar()) {
scrollbar.Paint(context);
scrollbar.Paint(context, paint_offset);
return;
}
......
......@@ -176,8 +176,9 @@ void Scrollbar::SetProportion(int visible_size, int total_size) {
SetNeedsPaintInvalidation(kAllParts);
}
void Scrollbar::Paint(GraphicsContext& context) const {
GetTheme().Paint(*this, context);
void Scrollbar::Paint(GraphicsContext& context,
const IntPoint& paint_offset) const {
GetTheme().Paint(*this, context, paint_offset);
}
void Scrollbar::AutoscrollTimerFired(TimerBase*) {
......
......@@ -124,7 +124,7 @@ class CORE_EXPORT Scrollbar : public GarbageCollected<Scrollbar>,
void SetProportion(int visible_size, int total_size);
void SetPressedPos(int p) { pressed_pos_ = p; }
void Paint(GraphicsContext&) const;
void Paint(GraphicsContext&, const IntPoint& paint_offset) const;
virtual bool IsSolidColor() const;
virtual bool IsOverlayScrollbar() const;
......
......@@ -49,12 +49,15 @@
namespace blink {
void ScrollbarTheme::Paint(const Scrollbar& scrollbar,
GraphicsContext& graphics_context) {
PaintTrackButtonsTickmarks(graphics_context, scrollbar, IntPoint());
GraphicsContext& graphics_context,
const IntPoint& paint_offset) {
PaintTrackButtonsTickmarks(graphics_context, scrollbar, paint_offset);
IntRect thumb_rect = ThumbRect(scrollbar);
if (HasThumb(scrollbar))
if (HasThumb(scrollbar)) {
IntRect thumb_rect = ThumbRect(scrollbar);
thumb_rect.MoveBy(paint_offset);
PaintThumbWithOpacity(graphics_context, scrollbar, thumb_rect);
}
}
ScrollbarPart ScrollbarTheme::HitTestRootFramePosition(
......
......@@ -54,7 +54,9 @@ class CORE_EXPORT ScrollbarTheme {
virtual void UpdateEnabledState(const Scrollbar&) {}
// |context|'s current space is the space of the scrollbar's FrameRect().
void Paint(const Scrollbar&, GraphicsContext& context);
void Paint(const Scrollbar&,
GraphicsContext& context,
const IntPoint& paint_offset);
ScrollbarPart HitTestRootFramePosition(const Scrollbar&, const IntPoint&);
......
<!doctype html>
<svg width="400" height="400">
<foreignObject x="200" y="200" width="200" height="200">
<div style="width: 100px; height: 100px; transform: scale(2); transform-origin: 0 0; overflow: scroll">
<div style="width: 1000px; height: 1000px; background: blue"></div>
</div>
</foreignObject>
</svg>
<!doctype html>
<title>foreignObject with scale transform and overflow:scroll</title>
<link rel="help" href="https://svgwg.org/svg2-draft/single-page.html#embedded-ForeignObjectElement"/>
<link rel="match" href="foreign-object-scale-scroll-ref.html">
<svg width="400" height="400">
<foreignObject x="100" y="100" transform="scale(2)" width="100" height="100" style="overflow: scroll">
<div style="width: 1000px; height: 1000px; background: blue"></div>
</foreignObject>
</svg>
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