Index: ui/views/view.cc |
diff --git a/ui/views/view.cc b/ui/views/view.cc |
index b39da4994275cb5067ff16a1f2cfbb886fcac57f..8a838858e36604583610ae126e9a0ff9588fac03 100644 |
--- a/ui/views/view.cc |
+++ b/ui/views/view.cc |
@@ -94,6 +94,37 @@ const View* GetHierarchyRoot(const View* view) { |
return root; |
} |
+/* |
+gfx::Rect GetPixelBounds(const ui::PaintContext& parent_context, |
+ const gfx::Vector2d& child_origin, |
+ const gfx::Size& child_size, |
+ const gfx::Size& parent_pixel_size, |
+ const gfx::Rect& parent_bounds) { |
+ float dsf = parent_context.device_scale_factor(); |
+ |
+ int right = child_origin.x() + child_size.width(); |
+ int bottom = child_origin.y() + child_size.height(); |
+ |
+ int new_x = std::round(child_origin.x() * dsf); |
+ int new_y = std::round(child_origin.y() * dsf); |
+ |
+ int new_right; |
+ int new_bottom; |
+ |
+ if (right == parent_bounds.width()) { |
+ new_right = parent_pixel_size.width(); |
+ } else { |
+ new_right = std::round(right * dsf); |
+ } |
+ if (bottom == parent_bounds.height()) { |
+ new_bottom = parent_pixel_size.height(); |
+ } else { |
+ new_bottom = std::round(bottom * dsf); |
+ } |
+ return gfx::Rect(new_x, new_y, new_right - new_x, new_bottom - new_y); |
+} |
+*/ |
+ |
} // namespace |
namespace internal { |
@@ -828,12 +859,32 @@ void View::SchedulePaintInRect(const gfx::Rect& rect) { |
void View::Paint(const ui::PaintContext& parent_context) { |
if (!ShouldPaint()) |
return; |
+ gfx::Vector2dF scale = parent_context.CanvasScale(); |
+ |
+ gfx::Point offset_to_parent; |
+ if (!layer()) { |
+ // 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. |
+ DCHECK(parent() || origin() == gfx::Point()); |
+ offset_to_parent = GetMirroredPosition(); |
+ } |
+ |
+ gfx::Rect pixel_bounds = |
+ parent_context.GetPixelBounds(gfx::Rect(offset_to_parent, size())); |
+ /* |
+ LOG(ERROR) << "ParentPixelSize:" |
+ << "parent bounds=" << parent_bounds.ToString() |
+ << ", parent pixel=" << parent_pixel_size.ToString() |
+ << ", my size=" << size().ToString() |
+ << ", m pixel=" << pixel_bounds.ToString(); |
+ */ |
- ui::PaintContext context(parent_context, GetPaintContextOffset()); |
+ ui::PaintContext context(parent_context, GetPaintContextOffset(pixel_bounds)); |
+ context.UpdateSizeAndDSF(pixel_bounds.size(), size()); |
bool is_invalidated = true; |
if (context.CanCheckInvalid()) { |
-#if DCHECK_IS_ON() |
+#if DCHECK_IS_ON() && 0 |
gfx::Vector2d offset; |
context.Visited(this); |
View* view = this; |
@@ -854,7 +905,7 @@ void View::Paint(const ui::PaintContext& parent_context) { |
// 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(pixel_bounds.size())); |
} |
TRACE_EVENT1("views", "View::Paint", "class", GetClassName()); |
@@ -870,24 +921,30 @@ void View::Paint(const ui::PaintContext& parent_context) { |
// 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(pixel_bounds); |
} else { |
gfx::Path clip_path_in_parent = clip_path_; |
clip_path_in_parent.offset(GetMirroredX(), y()); |
+ |
+ clip_path_in_parent.transform(SkMatrix::MakeScale( |
+ SkFloatToScalar(scale.x()), |
+ SkFloatToScalar(scale.y()))); |
clip_recorder.ClipPathWithAntiAliasing(clip_path_in_parent); |
} |
} |
ui::TransformRecorder transform_recorder(context); |
- SetupTransformRecorderForPainting(&transform_recorder); |
+ SetupTransformRecorderForPainting(&transform_recorder, |
+ GetPaintContextOffset(pixel_bounds)); |
// 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, pixel_bounds.size())) { |
+ ui::PaintRecorder recorder(context, pixel_bounds.size(), &paint_cache_, |
+ true); |
gfx::Canvas* canvas = recorder.canvas(); |
- gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, width(), |
+ gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, pixel_bounds.width(), |
flip_canvas_on_paint_for_rtl_ui_); |
// Delegate painting the contents of the View to the virtual OnPaint method. |
@@ -1944,27 +2001,29 @@ bool View::ShouldPaint() const { |
return visible_ && !size().IsEmpty(); |
} |
-gfx::Vector2d View::GetPaintContextOffset() const { |
+gfx::Vector2d View::GetPaintContextOffset(const gfx::Rect& pixel_bounds) 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. |
DCHECK(layer() || parent() || origin() == gfx::Point()); |
- return layer() ? gfx::Vector2d() : GetMirroredPosition().OffsetFromOrigin(); |
+ if (layer()) |
+ return gfx::Vector2d(); |
+ int mirrored_x = GetMirroredXForRect(pixel_bounds); |
+ return gfx::Vector2d(mirrored_x, pixel_bounds.y()); |
} |
void View::SetupTransformRecorderForPainting( |
- ui::TransformRecorder* recorder) const { |
+ ui::TransformRecorder* recorder, |
+ 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. |
+ // rather than relative to its parent.2 |
if (layer()) |
return; |
// 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); |
} |
@@ -1989,14 +2048,27 @@ void View::PaintDebugRects(const ui::PaintContext& parent_context) { |
if (!ShouldPaint()) |
return; |
- ui::PaintContext context(parent_context, GetPaintContextOffset()); |
+ //const gfx::Size& parent_pixel_size = parent_context.pixel_size(); |
+ //const gfx::Rect parent_bounds = parent() ? parent()->bounds() : bounds(); |
+ gfx::Point offset_to_parent; |
+ if (!layer()) { |
+ // 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. |
+ DCHECK(parent() || origin() == gfx::Point()); |
+ offset_to_parent = GetMirroredPosition(); |
+ } |
+ gfx::Rect pixel_bounds = parent_context.GetPixelBounds(gfx::Rect(offset_to_parent, size())); |
+ ui::PaintContext context(parent_context, GetPaintContextOffset(pixel_bounds)); |
+ context.UpdateSizeAndDSF(pixel_bounds.size(), size()); |
+ |
ui::TransformRecorder transform_recorder(context); |
- SetupTransformRecorderForPainting(&transform_recorder); |
+ SetupTransformRecorderForPainting(&transform_recorder, |
+ pixel_bounds.OffsetFromOrigin()); |
RecursivePaintHelper(&View::PaintDebugRects, context); |
// Draw outline rects for debugging. |
- ui::PaintRecorder recorder(context, size()); |
+ ui::PaintRecorder recorder(context, pixel_bounds.size(), &paint_cache_, true); |
gfx::Canvas* canvas = recorder.canvas(); |
const float scale = canvas->UndoDeviceScaleFactor(); |
gfx::RectF outline_rect(ScaleToEnclosedRect(GetLocalBounds(), scale)); |