Index: ui/views/view.cc |
diff --git a/ui/views/view.cc b/ui/views/view.cc |
index 19b9a6d98a5fa61200ea4ee55a8e46281f1d464c..b09be994b1fd52197ba472f8451a4aee1a943755 100644 |
--- a/ui/views/view.cc |
+++ b/ui/views/view.cc |
@@ -845,36 +845,46 @@ void View::SchedulePaintInRect(const gfx::Rect& rect) { |
} |
} |
-void View::Paint(const ui::PaintContext& parent_context) { |
+void View::Paint(const PaintInfo& parent_paint_info) { |
if (!ShouldPaint()) |
return; |
- ui::PaintContext context(parent_context, GetPaintContextOffset()); |
+ const gfx::Rect& parent_bounds = !parent() |
+ ? GetPaintRecordingBounds() |
+ : parent()->GetPaintRecordingBounds(); |
+ PaintInfo paint_info = PaintInfo::CreateChildPaintInfo( |
+ parent_paint_info, GetPaintRecordingBounds(), parent_bounds.size(), |
+ GetPaintScaleType()); |
+ |
+ const ui::PaintContext& context = paint_info.context(); |
bool is_invalidated = true; |
- if (context.CanCheckInvalid()) { |
+ if (paint_info.context().CanCheckInvalid()) { |
#if DCHECK_IS_ON() |
- gfx::Vector2d offset; |
- context.Visited(this); |
- View* view = this; |
- while (view->parent() && !view->layer()) { |
- DCHECK(view->GetTransform().IsIdentity()); |
- offset += view->GetMirroredPosition().OffsetFromOrigin(); |
- view = view->parent(); |
+ if (!context.is_pixel_canvas()) { |
+ gfx::Vector2d offset; |
+ context.Visited(this); |
+ View* view = this; |
+ while (view->parent() && !view->layer()) { |
+ DCHECK(view->GetTransform().IsIdentity()); |
+ offset += view->GetMirroredPosition().OffsetFromOrigin(); |
+ view = view->parent(); |
+ } |
+ // The offset in the PaintContext should be the offset up to the paint |
+ // root, which we compute and verify here. |
+ DCHECK_EQ(context.PaintOffset().x(), offset.x()); |
+ DCHECK_EQ(context.PaintOffset().y(), offset.y()); |
+ // The above loop will stop when |view| is the paint root, which should be |
+ // the root of the current paint walk, as verified by storing the root in |
+ // the PaintContext. |
+ DCHECK_EQ(context.RootVisited(), view); |
} |
- // The offset in the PaintContext should be the offset up to the paint root, |
- // which we compute and verify here. |
- DCHECK_EQ(context.PaintOffset().x(), offset.x()); |
- DCHECK_EQ(context.PaintOffset().y(), offset.y()); |
- // The above loop will stop when |view| is the paint root, which should be |
- // the root of the current paint walk, as verified by storing the root in |
- // the PaintContext. |
- DCHECK_EQ(context.RootVisited(), view); |
#endif |
// If the View wasn't invalidated, don't waste time painting it, the output |
// would be culled. |
- is_invalidated = context.IsRectInvalid(GetLocalBounds()); |
+ is_invalidated = |
+ context.IsRectInvalid(gfx::Rect(paint_info.paint_recording_size())); |
} |
TRACE_EVENT1("views", "View::Paint", "class", GetClassName()); |
@@ -883,29 +893,43 @@ void View::Paint(const ui::PaintContext& parent_context) { |
// rather than relative to its parent. |
// TODO(danakj): Rework clip and transform recorder usage here to use |
// std::optional once we can do so. |
- ui::ClipRecorder clip_recorder(parent_context); |
+ ui::ClipRecorder clip_recorder(parent_paint_info.context()); |
if (!layer()) { |
// Set the clip rect to the bounds of this View, or |clip_path_| if it's |
// been set. Note that the X (or left) position we pass to ClipRect takes |
// into consideration whether or not the View uses a right-to-left layout so |
// that we paint the View in its mirrored position if need be. |
if (clip_path_.isEmpty()) { |
- clip_recorder.ClipRect(GetMirroredBounds()); |
+ clip_recorder.ClipRect(gfx::Rect(paint_info.paint_recording_size()) + |
+ paint_info.offset_from_parent()); |
} else { |
gfx::Path clip_path_in_parent = clip_path_; |
- clip_path_in_parent.offset(GetMirroredX(), y()); |
+ |
+ // Transform |clip_path_| from local space to parent recording space. |
+ gfx::Transform to_parent_recording_space; |
+ |
+ gfx::PointF recording_scale = paint_info.paint_recording_scale(); |
+ to_parent_recording_space.Scale(SkFloatToScalar(recording_scale.x()), |
+ SkFloatToScalar(recording_scale.y())); |
+ to_parent_recording_space.Translate(paint_info.offset_from_parent()); |
+ |
+ clip_path_in_parent.transform(to_parent_recording_space.matrix()); |
clip_recorder.ClipPathWithAntiAliasing(clip_path_in_parent); |
} |
} |
ui::TransformRecorder transform_recorder(context); |
- SetupTransformRecorderForPainting(&transform_recorder); |
+ SetupTransformRecorderForPainting(&transform_recorder, |
+ paint_info.offset_from_parent()); |
// Note that the cache is not aware of the offset of the view |
// relative to the parent since painting is always done relative to |
// the top left of the individual view. |
- if (is_invalidated || !paint_cache_.UseCache(context, size())) { |
- ui::PaintRecorder recorder(context, size(), &paint_cache_); |
+ if (is_invalidated || |
+ !paint_cache_.UseCache(context, paint_info.paint_recording_size())) { |
+ ui::PaintRecorder recorder(context, paint_info.paint_recording_size(), |
+ paint_info.paint_recording_scale(), |
+ &paint_cache_); |
gfx::Canvas* canvas = recorder.canvas(); |
gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, width(), |
flip_canvas_on_paint_for_rtl_ui_); |
@@ -915,7 +939,7 @@ void View::Paint(const ui::PaintContext& parent_context) { |
} |
// View::Paint() recursion over the subtree. |
- PaintChildren(context); |
+ PaintChildren(paint_info); |
} |
void View::SetBackground(std::unique_ptr<Background> b) { |
@@ -1543,9 +1567,9 @@ void View::RemovedFromWidget() {} |
// Painting -------------------------------------------------------------------- |
-void View::PaintChildren(const ui::PaintContext& context) { |
+void View::PaintChildren(const PaintInfo& paint_info) { |
TRACE_EVENT1("views", "View::PaintChildren", "class", GetClassName()); |
- RecursivePaintHelper(&View::Paint, context); |
+ RecursivePaintHelper(&View::Paint, paint_info); |
} |
void View::OnPaint(gfx::Canvas* canvas) { |
@@ -1817,6 +1841,10 @@ int View::GetVerticalDragThreshold() { |
return kDefaultVerticalDragThreshold; |
} |
+PaintInfo::ScaleType View::GetPaintScaleType() const { |
+ return PaintInfo::ScaleType::kScaleToFit; |
+} |
+ |
// Debugging ------------------------------------------------------------------- |
#if !defined(NDEBUG) |
@@ -1969,15 +1997,17 @@ bool View::ShouldPaint() const { |
return visible_ && !size().IsEmpty(); |
} |
-gfx::Vector2d View::GetPaintContextOffset() const { |
- // If the View has a layer() then it is a paint root. Otherwise, we need to |
- // add the offset from the parent into the total offset from the paint root. |
+gfx::Rect View::GetPaintRecordingBounds() const { |
+ // If the View has a layer() then it is a paint root and no offset information |
+ // is needed. Otherwise, we need bounds that includes an offset from the |
+ // parent to add to the total offset from the paint root. |
DCHECK(layer() || parent() || origin() == gfx::Point()); |
- return layer() ? gfx::Vector2d() : GetMirroredPosition().OffsetFromOrigin(); |
+ return layer() ? GetLocalBounds() : GetMirroredBounds(); |
} |
void View::SetupTransformRecorderForPainting( |
- ui::TransformRecorder* recorder) const { |
+ ui::TransformRecorder* recorder, |
+ const gfx::Vector2d& offset_from_parent) const { |
// If the view is backed by a layer, it should paint with itself as the origin |
// rather than relative to its parent. |
if (layer()) |
@@ -1986,42 +2016,52 @@ void View::SetupTransformRecorderForPainting( |
// Translate the graphics such that 0,0 corresponds to where this View is |
// located relative to its parent. |
gfx::Transform transform_from_parent; |
- gfx::Vector2d offset_from_parent = GetMirroredPosition().OffsetFromOrigin(); |
transform_from_parent.Translate(offset_from_parent.x(), |
offset_from_parent.y()); |
- transform_from_parent.PreconcatTransform(GetTransform()); |
recorder->Transform(transform_from_parent); |
} |
-void View::RecursivePaintHelper(void (View::*func)(const ui::PaintContext&), |
- const ui::PaintContext& context) { |
+void View::RecursivePaintHelper(void (View::*func)(const PaintInfo&), |
+ const PaintInfo& info) { |
View::Views children = GetChildrenInZOrder(); |
DCHECK_EQ(child_count(), static_cast<int>(children.size())); |
for (auto* child : children) { |
if (!child->layer()) |
- (child->*func)(context); |
+ (child->*func)(info); |
} |
} |
void View::PaintFromPaintRoot(const ui::PaintContext& parent_context) { |
- Paint(parent_context); |
+ PaintInfo paint_info = PaintInfo::CreateRootPaintInfo( |
+ parent_context, layer() ? layer()->size() : size()); |
+ Paint(paint_info); |
if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
switches::kDrawViewBoundsRects)) |
- PaintDebugRects(parent_context); |
+ PaintDebugRects(paint_info); |
} |
-void View::PaintDebugRects(const ui::PaintContext& parent_context) { |
+void View::PaintDebugRects(const PaintInfo& parent_paint_info) { |
if (!ShouldPaint()) |
return; |
- ui::PaintContext context(parent_context, GetPaintContextOffset()); |
+ const gfx::Rect& parent_bounds = (layer() || !parent()) |
+ ? GetPaintRecordingBounds() |
+ : parent()->GetPaintRecordingBounds(); |
+ PaintInfo paint_info = PaintInfo::CreateChildPaintInfo( |
+ parent_paint_info, GetPaintRecordingBounds(), parent_bounds.size(), |
+ GetPaintScaleType()); |
+ |
+ const ui::PaintContext& context = paint_info.context(); |
+ |
ui::TransformRecorder transform_recorder(context); |
- SetupTransformRecorderForPainting(&transform_recorder); |
+ SetupTransformRecorderForPainting(&transform_recorder, |
+ paint_info.offset_from_parent()); |
- RecursivePaintHelper(&View::PaintDebugRects, context); |
+ RecursivePaintHelper(&View::PaintDebugRects, paint_info); |
// Draw outline rects for debugging. |
- ui::PaintRecorder recorder(context, size()); |
+ ui::PaintRecorder recorder(context, paint_info.paint_recording_size(), |
+ paint_info.paint_recording_scale(), &paint_cache_); |
gfx::Canvas* canvas = recorder.canvas(); |
const float scale = canvas->UndoDeviceScaleFactor(); |
gfx::RectF outline_rect(ScaleToEnclosedRect(GetLocalBounds(), scale)); |