| 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));
|
|
|