0

Add gfx::Transform::[Inverse]MapRect(const gfx::Rect&)

This follows blink::TransformationMatrix(const gfx::Rect&), to
prepare for combination of gfx::Transform and
blink::TransformationMatrix.

Code like the following
  gfx::RectF rect_f(rect);
  transform.TransformRect(&rect_f);
  gfx::Rect out_rect = gfx::ToEnclosingRect(rect_f);
is replaced with
  gfx::Rect out_rect = gfx::MapRect(rect);

Code in some unittests using gfx::ToRoundedRect(),
gfx::ToEnclosedRect() or gfx::ToNearestRect() instead of
gfx::ToEnclosingRect() as the last step are also replace with
the new code as long as the tests still pass. Similar code in
production code is kept as-is.

Bug: 1359528
Change-Id: Ic86333d48da459fc571240d80d513ca5efded699
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3935017
Owners-Override: danakj <danakj@chromium.org>
Reviewed-by: danakj <danakj@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1055517}
This commit is contained in:
Xianzhu Wang
2022-10-05 22:34:54 +00:00
committed by Chromium LUCI CQ
parent 9dac27aa95
commit 901b935e43
32 changed files with 157 additions and 169 deletions

@ -98,9 +98,12 @@ class FullscreenMagnifierControllerTest : public AshTestBase {
}
gfx::Rect GetViewport() const {
gfx::RectF bounds(0, 0, kRootWidth, kRootHeight);
GetRootWindow()->layer()->transform().TransformRectReverse(&bounds);
return gfx::ToEnclosingRect(bounds);
gfx::Rect bounds(0, 0, kRootWidth, kRootHeight);
return GetRootWindow()
->layer()
->transform()
.InverseMapRect(bounds)
.value_or(bounds);
}
std::string CurrentPointOfInterest() const {

@ -28,17 +28,15 @@ class AppDragIconProxyTest : public AshTestBase {
~AppDragIconProxyTest() override = default;
gfx::Rect GetTargetAppDragIconImageBounds(AppDragIconProxy* drag_icon_proxy) {
gfx::RectF layer_target_position(
drag_icon_proxy->GetImageLayerForTesting()->GetTargetBounds());
drag_icon_proxy->GetImageLayerForTesting()
->GetTargetTransform()
.TransformRect(&layer_target_position);
gfx::Rect layer_target_position =
drag_icon_proxy->GetImageLayerForTesting()
->GetTargetTransform()
.MapRect(
drag_icon_proxy->GetImageLayerForTesting()->GetTargetBounds());
gfx::Rect widget_target_bounds =
drag_icon_proxy->GetWidgetForTesting()->GetLayer()->GetTargetBounds();
layer_target_position.set_origin(
gfx::PointF(layer_target_position.x() + widget_target_bounds.x(),
layer_target_position.y() + widget_target_bounds.y()));
return gfx::ToNearestRect(layer_target_position);
layer_target_position.Offset(widget_target_bounds.OffsetFromOrigin());
return layer_target_position;
}
};

@ -90,9 +90,8 @@ void AshWindowTreeHostPlatform::ConfineCursorToBoundsInRoot(
if (!allow_confine_cursor())
return;
gfx::RectF bounds_f(bounds_in_root);
GetRootTransform().TransformRect(&bounds_f);
last_cursor_confine_bounds_in_pixels_ = gfx::ToEnclosingRect(bounds_f);
last_cursor_confine_bounds_in_pixels_ =
GetRootTransform().MapRect(bounds_in_root);
platform_window()->ConfineCursorToBounds(
last_cursor_confine_bounds_in_pixels_);
}

@ -108,14 +108,11 @@ gfx::Rect GetDisplayBoundsWithShelf(aura::Window* window) {
->display_configuration_controller()
->GetPrimaryMirroringDisplayForUnifiedDesktop();
DCHECK_NE(shelf_display.id(), display::kInvalidDisplayId);
gfx::RectF shelf_display_screen_bounds(shelf_display.bounds());
// Transform the bounds back to the unified host's coordinates.
auto inverse_unified_transform =
window->GetRootWindow()->GetHost()->GetInverseRootTransform();
inverse_unified_transform.TransformRect(&shelf_display_screen_bounds);
return gfx::ToEnclosingRect(shelf_display_screen_bounds);
return inverse_unified_transform.MapRect(shelf_display.bounds());
}
gfx::Rect SnapBoundsToDisplayEdge(const gfx::Rect& bounds,

@ -130,16 +130,14 @@ class HomeToOverviewNudgeControllerTest : public AshTestBase {
ASSERT_TRUE(nudge_widget);
EXPECT_TRUE(nudge_widget->IsVisible());
gfx::RectF nudge_bounds_f(
nudge_widget->GetNativeWindow()->GetTargetBounds());
nudge_widget->GetLayer()->transform().TransformRect(&nudge_bounds_f);
const gfx::Rect nudge_bounds = gfx::ToEnclosingRect(nudge_bounds_f);
const gfx::Rect nudge_bounds =
nudge_widget->GetLayer()->transform().MapRect(
nudge_widget->GetNativeWindow()->GetTargetBounds());
HotseatWidget* const hotseat = GetHotseatWidget();
gfx::RectF hotseat_bounds_f(hotseat->GetNativeWindow()->GetTargetBounds());
hotseat->GetLayerForNudgeAnimation()->transform().TransformRect(
&hotseat_bounds_f);
const gfx::Rect hotseat_bounds = gfx::ToEnclosingRect(hotseat_bounds_f);
const gfx::Rect hotseat_bounds =
hotseat->GetLayerForNudgeAnimation()->transform().MapRect(
hotseat->GetNativeWindow()->GetTargetBounds());
// Nudge and hotseat should have the same transform.
EXPECT_EQ(hotseat->GetLayerForNudgeAnimation()->transform(),

@ -1180,9 +1180,8 @@ void HotseatWidget::LayoutHotseatByAnimation(double target_opacity,
// between hidden and extended state use transform to animate. Clear any
// transform that may have been set by the previous animation, and update
// current bounds to match it.
gfx::RectF current_bounds_f(GetNativeView()->GetBoundsInScreen());
hotseat_layer->transform().TransformRect(&current_bounds_f);
gfx::Rect current_bounds = gfx::ToEnclosingRect(current_bounds_f);
gfx::Rect current_bounds =
hotseat_layer->transform().MapRect(GetNativeView()->GetBoundsInScreen());
// If the bounds size has not changed, set the target bounds immediately, and
// animate using transform.

@ -1024,9 +1024,8 @@ void ShelfWidget::UpdateLayout(bool animate) {
// When the |shelf_widget_| needs to reverse the direction of the current
// animation, we must take into account the transform when calculating the
// current shelf widget bounds.
gfx::RectF transformed_bounds(current_shelf_bounds);
GetLayer()->transform().TransformRect(&transformed_bounds);
current_shelf_bounds = gfx::ToEnclosedRect(transformed_bounds);
current_shelf_bounds =
GetLayer()->transform().MapRect(current_shelf_bounds);
}
gfx::Transform shelf_widget_target_transform;

@ -3256,9 +3256,9 @@ TEST_F(DesksTest, AutohiddenShelfAnimatesAfterDeskSwitch) {
// Since the layer transform animation is just starting, the transformed
// bounds should still be hidden. If this fails, the change was not animated.
gfx::RectF transformed_bounds(shelf_widget->GetWindowBoundsInScreen());
shelf_widget->GetLayer()->transform().TransformRect(&transformed_bounds);
EXPECT_EQ(gfx::ToEnclosedRect(transformed_bounds), hidden_shelf_bounds);
gfx::Rect transformed_bounds = shelf_widget->GetLayer()->transform().MapRect(
shelf_widget->GetWindowBoundsInScreen());
EXPECT_EQ(transformed_bounds, hidden_shelf_bounds);
EXPECT_EQ(shelf_widget->GetWindowBoundsInScreen(), shown_shelf_bounds);
// Let's wait until the shelf animates to a fully shown state.

@ -53,9 +53,7 @@ gfx::Rect GetVisibleBounds(ui::Layer* child_layer,
use_target_transform ? animating_layer->GetTargetTransform()
: animating_layer->transform();
DCHECK(animating_layer_transform.IsIdentityOr2DTranslation());
gfx::RectF bounds(child_layer->bounds());
animating_layer_transform.TransformRect(&bounds);
return gfx::ToRoundedRect(bounds);
return animating_layer_transform.MapRect(child_layer->bounds());
}
gfx::Rect GetTargetVisibleBounds(ui::Layer* child_layer,

@ -4797,9 +4797,8 @@ TEST_F(SplitViewOverviewSessionTest, Clipping) {
EXPECT_FALSE(preview_layer->clip_rect().IsEmpty());
EXPECT_FALSE(preview_layer->transform().IsIdentity());
// The clip rect is affected by |preview_layer|'s transform so apply it.
gfx::RectF clip_rect3_f(preview_layer->clip_rect());
preview_layer->transform().TransformRect(&clip_rect3_f);
const gfx::Rect clip_rects3 = gfx::ToEnclosedRect(clip_rect3_f);
const gfx::Rect clip_rects3 =
preview_layer->transform().MapRect(preview_layer->clip_rect());
EXPECT_TRUE(aspect_ratio_near(clip_rects3, split_view_bounds_right));
EXPECT_TRUE(aspect_ratio_near(
gfx::ToEnclosedRect(item3->GetWindowTargetBoundsWithInsets()),

@ -99,7 +99,6 @@ gfx::Rect OverviewTestBase::GetTransformedTargetBounds(aura::Window* window) {
gfx::Rect OverviewTestBase::GetTransformedBoundsInRootWindow(
aura::Window* window) {
gfx::RectF bounds = gfx::RectF(gfx::SizeF(window->bounds().size()));
aura::Window* root = window->GetRootWindow();
CHECK(window->layer());
CHECK(root->layer());
@ -108,8 +107,7 @@ gfx::Rect OverviewTestBase::GetTransformedBoundsInRootWindow(
&transform)) {
return gfx::Rect();
}
transform.TransformRect(&bounds);
return gfx::ToEnclosingRect(bounds);
return transform.MapRect(gfx::Rect(window->bounds().size()));
}
OverviewItem* OverviewTestBase::GetDropTarget(int grid_index) {

@ -1244,7 +1244,7 @@ TEST_P(SurfaceTest, ScaledSurfaceQuad) {
->quad_list.back()
->shared_quad_state->clip_rect);
auto testing_rect = gfx::RectF(gfx::PointF(0, 0), gfx::SizeF(256, 256));
gfx::Rect testing_rect(256, 256);
// To get 32,32 -> 160,160 into the correct position it must be translated
// backwards and scaled 0.5x in Y, then everything is scaled by the scale
// factor.
@ -1258,8 +1258,7 @@ TEST_P(SurfaceTest, ScaledSurfaceQuad) {
if (gfx::Transform() == frame.render_pass_list.back()
->quad_list.back()
->shared_quad_state->quad_to_target_transform) {
expected_transform.TransformRect(&testing_rect);
auto expected_rect = gfx::ToNearestRect(testing_rect);
auto expected_rect = expected_transform.MapRect(testing_rect);
EXPECT_EQ(expected_rect,
frame.render_pass_list.back()->quad_list.back()->rect);
} else {
@ -1267,7 +1266,7 @@ TEST_P(SurfaceTest, ScaledSurfaceQuad) {
frame.render_pass_list.back()
->quad_list.back()
->shared_quad_state->quad_to_target_transform);
EXPECT_EQ(gfx::ToNearestRect(testing_rect),
EXPECT_EQ(testing_rect,
frame.render_pass_list.back()->quad_list.back()->rect);
}
}

@ -152,9 +152,8 @@ void FromYUVQuad(const YUVVideoDrawQuad* quad,
if (quad->shared_quad_state->clip_rect) {
// Clip rect is in quad target space, and must be transformed to root target
// space.
gfx::RectF clip_rect = gfx::RectF(*quad->shared_quad_state->clip_rect);
transform_to_root_target.TransformRect(&clip_rect);
dc_layer->clip_rect = gfx::ToEnclosingRect(clip_rect);
dc_layer->clip_rect =
transform_to_root_target.MapRect(*quad->shared_quad_state->clip_rect);
}
dc_layer->color_space = quad->video_color_space;
dc_layer->protected_video_type = quad->protected_video_type;
@ -214,10 +213,8 @@ void FromTextureQuad(const TextureDrawQuad* quad,
if (quad->shared_quad_state->clip_rect) {
// Clip rect is in quad target space, and must be transformed to root target
// space.
gfx::RectF clip_rect =
gfx::RectF(quad->shared_quad_state->clip_rect.value_or(gfx::Rect()));
transform_to_root_target.TransformRect(&clip_rect);
dc_layer->clip_rect = gfx::ToEnclosingRect(clip_rect);
dc_layer->clip_rect = transform_to_root_target.MapRect(
quad->shared_quad_state->clip_rect.value_or(gfx::Rect()));
}
dc_layer->color_space = gfx::ColorSpace::CreateSRGB();
@ -627,10 +624,9 @@ void DCLayerOverlayProcessor::InsertDebugBorderDrawQuad(
// Add debug borders for overlays/underlays
for (const auto& dc_layer : *dc_layer_overlays) {
gfx::RectF overlay_rect(dc_layer.quad_rect);
dc_layer.transform.TransformRect(&overlay_rect);
gfx::Rect overlay_rect = dc_layer.transform.MapRect(dc_layer.quad_rect);
if (dc_layer.clip_rect)
overlay_rect.Intersect(gfx::RectF(*dc_layer.clip_rect));
overlay_rect.Intersect(*dc_layer.clip_rect);
// Overlay:red, Underlay:blue.
SkColor4f border_color =
@ -640,10 +636,9 @@ void DCLayerOverlayProcessor::InsertDebugBorderDrawQuad(
quad_list.begin(), 1u);
auto* debug_quad = static_cast<DebugBorderDrawQuad*>(*it);
gfx::Rect rect = gfx::ToEnclosingRect(overlay_rect);
rect.Inset(kDCLayerDebugBorderInsets);
debug_quad->SetNew(shared_quad_state, rect, rect, border_color,
kDCLayerDebugBorderWidth);
overlay_rect.Inset(kDCLayerDebugBorderInsets);
debug_quad->SetNew(shared_quad_state, overlay_rect, overlay_rect,
border_color, kDCLayerDebugBorderWidth);
}
// Mark the entire output as damaged because the border quads might not be

@ -145,9 +145,7 @@ gfx::Rect OverlayProcessorSurfaceControl::GetOverlayDamageRectForOutputSurface(
viewport_size_.width());
auto transform = gfx::OverlayTransformToTransform(
display_transform_, gfx::SizeF(viewport_size_pre_display_transform));
gfx::RectF transformed_rect(candidate.display_rect);
transform.TransformRect(&transformed_rect);
return gfx::ToEnclosedRect(transformed_rect);
return transform.MapRect(gfx::ToEnclosingRect(candidate.display_rect));
}
void OverlayProcessorSurfaceControl::SetDisplayTransformHint(

@ -66,8 +66,7 @@ bool OverlayStrategyUnderlayCast::Attempt(
continue;
const auto& transform = quad->shared_quad_state->quad_to_target_transform;
gfx::RectF quad_rect = gfx::RectF(quad->rect);
transform.TransformRect(&quad_rect);
gfx::Rect quad_rect = transform.MapRect(quad->rect);
bool is_underlay = false;
if (!found_underlay) {
@ -93,9 +92,9 @@ bool OverlayStrategyUnderlayCast::Attempt(
}
if (is_underlay) {
content_rect.Subtract(gfx::ToEnclosedRect(quad_rect));
content_rect.Subtract(quad_rect);
} else {
content_rect.Union(gfx::ToEnclosingRect(quad_rect));
content_rect.Union(quad_rect);
}
}
@ -197,8 +196,7 @@ bool OverlayStrategyUnderlayCast::AttemptPrioritized(
continue;
const auto& transform = quad->shared_quad_state->quad_to_target_transform;
gfx::RectF quad_rect = gfx::RectF(quad->rect);
transform.TransformRect(&quad_rect);
gfx::Rect quad_rect = transform.MapRect(quad->rect);
bool is_underlay = false;
if (!found_underlay) {
@ -224,9 +222,9 @@ bool OverlayStrategyUnderlayCast::AttemptPrioritized(
}
if (is_underlay) {
content_rect.Subtract(gfx::ToEnclosedRect(quad_rect));
content_rect.Subtract(quad_rect);
} else {
content_rect.Union(gfx::ToEnclosingRect(quad_rect));
content_rect.Union(quad_rect);
}
}

@ -2406,7 +2406,7 @@ void SurfaceAggregator::CreateDeJellyRenderPassQuads(
// Compute the required renderpass rect in target space.
// First, find the un-transformed visible rect.
gfx::RectF render_pass_visible_rect_f(state->visible_quad_layer_rect);
gfx::Rect render_pass_visible_rect = state->visible_quad_layer_rect;
// Next, if this is a RenderPass quad, find any filters and expand the
// visible rect.
if (quad->material == DrawQuad::Material::kCompositorRenderPass) {
@ -2414,16 +2414,15 @@ void SurfaceAggregator::CreateDeJellyRenderPassQuads(
CompositorRenderPassDrawQuad::MaterialCast(quad)->render_pass_id});
for (auto& rp : *dest_pass_list_) {
if (rp->id == target_id) {
render_pass_visible_rect_f = gfx::RectF(
rp->filters.MapRect(state->visible_quad_layer_rect, SkMatrix()));
render_pass_visible_rect =
rp->filters.MapRect(state->visible_quad_layer_rect, SkMatrix());
break;
}
}
}
// Next, find the enclosing Rect for the transformed target space RectF.
state->quad_to_target_transform.TransformRect(&render_pass_visible_rect_f);
gfx::Rect render_pass_visible_rect =
gfx::ToEnclosingRect(render_pass_visible_rect_f);
render_pass_visible_rect =
state->quad_to_target_transform.MapRect(render_pass_visible_rect);
// Finally, expand by our un_clip amounts.
render_pass_visible_rect.Inset(
gfx::Insets::TLBR(-un_clip_top, 0, -un_clip_bottom, 0));

@ -3763,11 +3763,8 @@ bool TransformPointAndRectToRootView(RenderWidgetHostViewBase* view,
if (transformed_point)
*transformed_point = transform_to_main_frame.MapPoint(*transformed_point);
if (transformed_rect) {
gfx::RectF transformed_rect_f(*transformed_rect);
transform_to_main_frame.TransformRect(&transformed_rect_f);
*transformed_rect = gfx::ToEnclosingRect(transformed_rect_f);
}
if (transformed_rect)
*transformed_rect = transform_to_main_frame.MapRect(*transformed_rect);
return true;
}

@ -6938,9 +6938,7 @@ class SitePerProcessHitTestDataGenerationBrowserTest
gfx::Rect AxisAlignedLayoutRectFromHitTest(
const viz::AggregatedHitTestRegion& hit_test_region) {
DCHECK(hit_test_region.transform.Preserves2dAxisAlignment());
gfx::RectF rect(hit_test_region.rect);
hit_test_region.transform.TransformRect(&rect);
return gfx::ToEnclosingRect(rect);
return hit_test_region.transform.MapRect(hit_test_region.rect);
}
public:

@ -2104,13 +2104,8 @@ void LocalFrame::SetViewportIntersectionFromParent(
intersection_state.main_frame_intersection ||
intersection_state_.main_frame_transform !=
intersection_state.main_frame_transform) {
gfx::RectF transform_rect =
gfx::RectF(gfx::Rect(intersection_state.main_frame_intersection));
intersection_state.main_frame_transform.TransformRect(&transform_rect);
gfx::Rect rect = ToEnclosingRect(
gfx::RectF(transform_rect.x(), transform_rect.y(),
transform_rect.width(), transform_rect.height()));
gfx::Rect rect = intersection_state.main_frame_transform.MapRect(
intersection_state.main_frame_intersection);
// Return <0, 0, 0, 0> if there is no area.
if (rect.IsEmpty())

@ -100,10 +100,8 @@ SkIRect ComputeClippedAndTransformedBounds(
const gfx::Transform& transform_relative_to_root,
const SkIRect* clipped_bounds) {
DCHECK(transform_relative_to_root.Preserves2dAxisAlignment());
gfx::RectF transformed_bounds(bounds);
transform_relative_to_root.TransformRect(&transformed_bounds);
SkIRect skirect_bounds =
gfx::RectToSkIRect(gfx::ToEnclosedRect(transformed_bounds));
gfx::Rect transformed_bounds = transform_relative_to_root.MapRect(bounds);
SkIRect skirect_bounds = gfx::RectToSkIRect(transformed_bounds);
// If necessary, clip the bounds.
if (clipped_bounds && !skirect_bounds.intersect(*clipped_bounds))
return SkIRect::MakeEmpty();

@ -736,9 +736,7 @@ void WindowTreeHost::OnDisplayMetricsChanged(const display::Display& display,
gfx::Rect WindowTreeHost::GetTransformedRootWindowBoundsFromPixelSize(
const gfx::Size& size_in_pixels) const {
gfx::RectF new_bounds = gfx::RectF(gfx::Rect(size_in_pixels));
GetInverseRootTransform().TransformRect(&new_bounds);
return gfx::ToEnclosingRect(new_bounds);
return GetInverseRootTransform().MapRect(gfx::Rect(size_in_pixels));
}
void WindowTreeHost::SetNativeWindowOcclusionEnabled(bool enable) {

@ -3752,9 +3752,7 @@ class WindowActualScreenBoundsTest
void OnTranslationAnimationProgressed(const gfx::Rect& child_initial_bounds,
const gfx::Transform& transform) const {
gfx::RectF current_screen_bounds(child_initial_bounds);
transform.TransformRect(&current_screen_bounds);
EXPECT_EQ(gfx::ToEnclosedRect(current_screen_bounds),
EXPECT_EQ(transform.MapRect(child_initial_bounds),
child_->GetActualBoundsInScreen());
}

@ -13,6 +13,7 @@
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/quaternion.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/rrect_f.h"
#include "ui/gfx/geometry/skia_conversions.h"
#include "ui/gfx/geometry/transform_util.h"
@ -496,6 +497,15 @@ void Transform::TransformRect(RectF* rect) const {
*rect = SkRectToRectF(src);
}
Rect Transform::MapRect(const Rect& rect) const {
if (IsIdentity())
return rect;
RectF rect_f(rect);
TransformRect(&rect_f);
return ToEnclosingRect(rect_f);
}
bool Transform::TransformRectReverse(RectF* rect) const {
if (IsIdentity())
return true;
@ -510,6 +520,16 @@ bool Transform::TransformRectReverse(RectF* rect) const {
return true;
}
absl::optional<Rect> Transform::InverseMapRect(const Rect& rect) const {
if (IsIdentity())
return rect;
RectF rect_f(rect);
if (TransformRectReverse(&rect_f))
return ToEnclosingRect(rect_f);
return absl::nullopt;
}
bool Transform::TransformRRectF(RRectF* rrect) const {
// We want this to fail only in cases where our
// Transform::Preserves2dAxisAlignment returns false. However,

@ -18,6 +18,7 @@ namespace gfx {
class AxisTransform2d;
class BoxF;
class Rect;
class RectF;
class RRectF;
class Point;
@ -334,12 +335,14 @@ class GEOMETRY_SKIA_EXPORT Transform {
// |rect| will be the smallest axis aligned bounding rect containing the
// transformed rect.
void TransformRect(RectF* rect) const;
[[nodiscard]] Rect MapRect(const Rect& rect) const;
// Applies the reverse transformation on the given rect. After the function
// completes, |rect| will be the smallest axis aligned bounding rect
// containing the transformed rect. Returns false if the matrix cannot be
// inverted.
bool TransformRectReverse(RectF* rect) const;
[[nodiscard]] absl::optional<Rect> InverseMapRect(const Rect& rect) const;
// Applies transformation on the given |rrect|. Returns false if the transform
// matrix cannot be applied to rrect.

@ -2752,27 +2752,56 @@ TEST(XFormTest, To2dTranslation) {
}
TEST(XFormTest, TransformRect) {
Transform translation;
translation.Translate(3.f, 7.f);
RectF rect(1.f, 2.f, 3.f, 4.f);
RectF expected(4.f, 9.f, 3.f, 4.f);
auto translation = Transform::MakeTranslation(3.25f, 7.75f);
RectF rect(1.25f, 2.5f, 3.75f, 4.f);
RectF expected(4.5f, 10.25f, 3.75f, 4.f);
translation.TransformRect(&rect);
EXPECT_EQ(expected.ToString(), rect.ToString());
EXPECT_EQ(expected, rect);
expected = rect;
Transform().TransformRect(&rect);
EXPECT_EQ(expected, rect);
auto singular = Transform::MakeScale(0.f);
singular.TransformRect(&rect);
EXPECT_EQ(RectF(0, 0, 0, 0), rect);
}
TEST(XFormTest, MapIntRect) {
auto translation = Transform::MakeTranslation(3.25f, 7.75f);
EXPECT_EQ(Rect(4, 9, 4, 5), translation.MapRect(Rect(1, 2, 3, 4)));
EXPECT_EQ(Rect(1, 2, 3, 4), Transform().MapRect(Rect(1, 2, 3, 4)));
auto singular = Transform::MakeScale(0.f);
EXPECT_EQ(Rect(0, 0, 0, 0), singular.MapRect(Rect(1, 2, 3, 4)));
}
TEST(XFormTest, TransformRectReverse) {
Transform translation;
translation.Translate(3.f, 7.f);
RectF rect(1.f, 2.f, 3.f, 4.f);
RectF expected(-2.f, -5.f, 3.f, 4.f);
auto translation = Transform::MakeTranslation(3.25f, 7.75f);
RectF rect(1.25f, 2.5f, 3.75f, 4.f);
RectF expected(-2.f, -5.25f, 3.75f, 4.f);
EXPECT_TRUE(translation.TransformRectReverse(&rect));
EXPECT_EQ(expected.ToString(), rect.ToString());
Transform singular;
singular.Scale3d(0.f, 0.f, 0.f);
expected = rect;
EXPECT_TRUE(Transform().TransformRectReverse(&rect));
EXPECT_EQ(expected, rect);
auto singular = Transform::MakeScale(0.f);
EXPECT_FALSE(singular.TransformRectReverse(&rect));
}
TEST(XFormTest, InverseMapIntRect) {
auto translation = Transform::MakeTranslation(3.25f, 7.75f);
EXPECT_EQ(Rect(-3, -6, 4, 5), translation.InverseMapRect(Rect(1, 2, 3, 4)));
EXPECT_EQ(Rect(1, 2, 3, 4), Transform().InverseMapRect(Rect(1, 2, 3, 4)));
auto singular = Transform::MakeScale(0.f);
EXPECT_FALSE(singular.InverseMapRect(Rect(1, 2, 3, 4)));
}
TEST(XFormTest, TransformRRectF) {
Transform translation;
translation.Translate(-3.f, -7.f);

@ -1232,9 +1232,7 @@ TEST_F(DirectCompositionPixelTest, ResizeVideoLayer) {
// chain to |new_on_screen_rect| which fits the monitor.
surface_->GetSwapChainVisualInfoForTesting(0, &transform, &offset,
&clip_rect);
gfx::RectF new_on_screen_rect = gfx::RectF(100, 100);
transform.TransformRect(&new_on_screen_rect);
EXPECT_EQ(gfx::Rect(monitor_size), gfx::ToEnclosingRect(new_on_screen_rect));
EXPECT_EQ(gfx::Rect(monitor_size), transform.MapRect(gfx::Rect(100, 100)));
}
TEST_F(DirectCompositionPixelTest, SwapChainImage) {

@ -568,15 +568,11 @@ bool SwapChainPresenter::AdjustSwapChainToFullScreenSizeIfNeeded(
visual_transform->PostTranslate(-new_origin.OffsetFromOrigin());
}
#if DCHECK_IS_ON()
// The new transform matrix should transform the swap chain to the monitor
// rect.
gfx::Rect new_swap_chain_rect = gfx::Rect(*swap_chain_size);
new_swap_chain_rect.set_origin(params.quad_rect.origin());
gfx::RectF new_onscreen_rect(new_swap_chain_rect);
visual_transform->TransformRect(&new_onscreen_rect);
DCHECK_EQ(gfx::ToEnclosingRect(new_onscreen_rect), gfx::Rect(monitor_size));
#endif
DCHECK_EQ(visual_transform->MapRect(
gfx::Rect(params.quad_rect.origin(), *swap_chain_size)),
gfx::Rect(monitor_size));
return true;
}
@ -655,11 +651,8 @@ void SwapChainPresenter::AdjustSwapChainForFullScreenLetterboxing(
#if DCHECK_IS_ON()
// The new transform matrix should transform the swap chain correctly
gfx::Rect new_swap_chain_rect = gfx::Rect(*swap_chain_size);
new_swap_chain_rect.set_origin(params.quad_rect.origin());
gfx::RectF new_onscreen_rect(new_swap_chain_rect);
visual_transform->TransformRect(&new_onscreen_rect);
gfx::Rect result_rect = gfx::ToEnclosingRect(new_onscreen_rect);
gfx::Rect new_swap_chain_rect(params.quad_rect.origin(), *swap_chain_size);
gfx::Rect result_rect = visual_transform->MapRect(new_swap_chain_rect);
if (IsWithinMargin(clipped_onscreen_rect.x(), 0)) {
DCHECK_EQ(result_rect.x(), 0);
DCHECK_EQ(result_rect.width(), monitor_size.width());
@ -683,11 +676,9 @@ gfx::Size SwapChainPresenter::CalculateSwapChainSize(
gfx::Size swap_chain_size = params.content_rect.size();
if (swap_chain_size.IsEmpty())
return gfx::Size();
gfx::RectF bounds(params.quad_rect);
if (bounds.IsEmpty())
if (params.quad_rect.IsEmpty())
return gfx::Size();
params.transform.TransformRect(&bounds);
gfx::Rect overlay_onscreen_rect = gfx::ToEnclosingRect(bounds);
gfx::Rect overlay_onscreen_rect = params.transform.MapRect(params.quad_rect);
// If transform isn't a scale or translation then swap chain can't be promoted
// to an overlay so avoid blitting to a large surface unnecessarily. Also,
@ -1266,9 +1257,7 @@ bool SwapChainPresenter::PresentDCOMPSurface(
dcomp_surface_proxy->SetParentWindow(layer_tree_->window());
// Apply transform to video and notify DCOMPTexture.
gfx::RectF on_screen_bounds(params.quad_rect);
params.transform.TransformRect(&on_screen_bounds);
dcomp_surface_proxy->SetRect(gfx::ToEnclosingRect(on_screen_bounds));
dcomp_surface_proxy->SetRect(params.transform.MapRect(params.quad_rect));
// If |dcomp_surface_proxy| size is {1, 1}, the texture was initialized
// without knowledge of output size; reset |content_| so it's not added to the

@ -2123,9 +2123,7 @@ TEST_P(WaylandWindowTest, WaylandPopupInitialBufferScale) {
const int32_t effective_scale = entered_output.output->GetScale();
gfx::Transform transform;
transform.Scale(effective_scale, effective_scale);
gfx::RectF rect_in_pixels = gfx::RectF(bounds_dip);
transform.TransformRect(&rect_in_pixels);
gfx::Rect wayland_popup_bounds = gfx::ToEnclosingRect(rect_in_pixels);
gfx::Rect wayland_popup_bounds = transform.MapRect(bounds_dip);
std::unique_ptr<WaylandWindow> wayland_popup =
CreateWaylandWindowWithParams(PlatformWindowType::kMenu,

@ -106,13 +106,10 @@ bool GrabWindowSnapshot(gfx::NativeWindow window_handle,
DCHECK(host);
HWND hwnd = host->GetAcceleratedWidget();
gfx::RectF window_bounds_in_pixels(window_bounds);
host->GetRootTransform().TransformRect(&window_bounds_in_pixels);
gfx::RectF snapshot_bounds_in_pixels(snapshot_bounds);
host->GetRootTransform().TransformRect(&snapshot_bounds_in_pixels);
gfx::Rect snapshot_bounds_in_pixels =
host->GetRootTransform().MapRect(snapshot_bounds);
gfx::Rect expanded_window_bounds_in_pixels =
gfx::ToEnclosingRect(window_bounds_in_pixels);
host->GetRootTransform().MapRect(window_bounds);
RECT client_area;
::GetClientRect(hwnd, &client_area);
gfx::Rect client_area_rect(client_area);
@ -120,9 +117,8 @@ bool GrabWindowSnapshot(gfx::NativeWindow window_handle,
expanded_window_bounds_in_pixels.Intersect(client_area_rect);
return internal::GrabHwndSnapshot(
hwnd, gfx::ToEnclosingRect(snapshot_bounds_in_pixels),
expanded_window_bounds_in_pixels, image);
return internal::GrabHwndSnapshot(hwnd, snapshot_bounds_in_pixels,
expanded_window_bounds_in_pixels, image);
}
void GrabWindowSnapshotAsync(gfx::NativeWindow window,

@ -514,11 +514,10 @@ gfx::Rect View::GetVisibleBounds() const {
}
if (vis_bounds.IsEmpty())
return vis_bounds;
// Convert back to this views coordinate system.
gfx::RectF views_vis_bounds(vis_bounds);
transform.TransformRectReverse(&views_vis_bounds);
// Partially visible pixels should be considered visible.
return gfx::ToEnclosingRect(views_vis_bounds);
// Convert back to this views coordinate system. This mapping returns the
// enclosing rect, which is good because partially visible pixels should
// be considered visible.
return transform.InverseMapRect(vis_bounds).value_or(vis_bounds);
}
gfx::Rect View::GetBoundsInScreen() const {
@ -1114,11 +1113,11 @@ void View::ConvertRectToScreen(const View* src, gfx::Rect* rect) {
}
gfx::Rect View::ConvertRectToParent(const gfx::Rect& rect) const {
gfx::RectF x_rect = gfx::RectF(rect);
GetTransform().TransformRect(&x_rect);
// This mapping returns the enclosing rect, which is good because pixels that
// partially occupy in the parent should be included.
gfx::Rect x_rect = GetTransform().MapRect(rect);
x_rect.Offset(GetMirroredPosition().OffsetFromOrigin());
// Pixels we partially occupy in the parent should be included.
return gfx::ToEnclosingRect(x_rect);
return x_rect;
}
gfx::Rect View::ConvertRectToWidget(const gfx::Rect& rect) const {

@ -952,16 +952,14 @@ void DesktopWindowTreeHostPlatform::OnWorkspaceChanged() {
gfx::Rect DesktopWindowTreeHostPlatform::ToDIPRect(
const gfx::Rect& rect_in_pixels) const {
gfx::RectF rect_in_dip = gfx::RectF(rect_in_pixels);
GetRootTransform().TransformRectReverse(&rect_in_dip);
return gfx::ToEnclosingRect(rect_in_dip);
return GetRootTransform()
.InverseMapRect(rect_in_pixels)
.value_or(rect_in_pixels);
}
gfx::Rect DesktopWindowTreeHostPlatform::ToPixelRect(
const gfx::Rect& rect_in_dip) const {
gfx::RectF rect_in_pixels = gfx::RectF(rect_in_dip);
GetRootTransform().TransformRect(&rect_in_pixels);
return gfx::ToEnclosingRect(rect_in_pixels);
return GetRootTransform().MapRect(rect_in_dip);
}
Widget* DesktopWindowTreeHostPlatform::GetWidget() {

@ -248,10 +248,7 @@ gfx::Rect GetLayerWorldBoundsAfterTransform(ui::Layer* layer,
gfx::Transform in_world = transform;
GetTransformRelativeToRoot(layer, &in_world);
gfx::RectF transformed = gfx::RectF(layer->bounds());
in_world.TransformRect(&transformed);
return gfx::ToEnclosingRect(transformed);
return in_world.MapRect(layer->bounds());
}
// Augment the host window so that the enclosing bounds of the full