Commit 0064df35 authored by Dmitry Gozman's avatar Dmitry Gozman Committed by Commit Bot

[DevTools] Fix taking screenshot with viewport override

When passing clip (which translates to viewport override), we use it
as a visible rect override. Clip/viewport in the protocol uses document
coordinates (relative to the 0;0 of the document), but visible rect
is relative to the frame. For clipping to work, we should translate
the coordinates.

This bug does not usually manifest due to kPixelDistanceToRecord
inflation of the interesting rect (see composited_layer_mapping.cc),
which paints interesetings rect +4000px in every direction. If scroll
position is no more than 4000, this compensates for the wrong visible
rect override.

Bug: none
Change-Id: I9c994c08da379c76c56523969f27c049be77d9a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2068890Reviewed-by: default avatarMathias Bynens <mathias@chromium.org>
Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Reviewed-by: default avatarAndrey Kosyakov <caseq@chromium.org>
Commit-Queue: Dmitry Gozman <dgozman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#744777}
parent 4d6a5015
......@@ -4997,11 +4997,11 @@ TEST_F(WebViewTest, ViewportOverrideAdaptsToScaleAndScroll) {
.Translate(100, 150)
.Scale(1. / 1.5f);
EXPECT_EQ(expected_matrix, web_view_impl->GetDeviceEmulationTransform());
// Page scroll and scale are irrelevant for visible rect.
// Scale is irrelevant for visible rect.
{
IntRect visible_rect(1, 2, 3, 4);
dev_tools_emulator->OverrideVisibleRect(IntSize(100, 150), &visible_rect);
EXPECT_EQ(IntRect(50, 55, 50, 75), visible_rect); // Was modified.
EXPECT_EQ(IntRect(50 - 100, 55 - 150, 50, 75), visible_rect);
}
// Transform adapts to scroll changes.
......@@ -5014,11 +5014,11 @@ TEST_F(WebViewTest, ViewportOverrideAdaptsToScaleAndScroll) {
.Translate(50, 55)
.Scale(1. / 1.5f);
EXPECT_EQ(expected_matrix, web_view_impl->GetDeviceEmulationTransform());
// Visible rect doesn't change.
// Visible rect adapts to scroll change.
{
IntRect visible_rect(1, 2, 3, 4);
dev_tools_emulator->OverrideVisibleRect(IntSize(100, 150), &visible_rect);
EXPECT_EQ(IntRect(50, 55, 50, 75), visible_rect); // Was modified.
EXPECT_EQ(IntRect(50 - 50, 55 - 55, 50, 75), visible_rect);
}
// Transform adapts to page scale changes.
......@@ -5033,7 +5033,7 @@ TEST_F(WebViewTest, ViewportOverrideAdaptsToScaleAndScroll) {
{
IntRect visible_rect(1, 2, 3, 4);
dev_tools_emulator->OverrideVisibleRect(IntSize(100, 150), &visible_rect);
EXPECT_EQ(IntRect(50, 55, 50, 75), visible_rect); // Was modified.
EXPECT_EQ(IntRect(50 - 50, 55 - 55, 50, 75), visible_rect);
}
}
......
......@@ -421,15 +421,19 @@ TransformationMatrix DevToolsEmulator::ComputeRootLayerTransform() {
return transform;
}
void DevToolsEmulator::OverrideVisibleRect(const IntSize& viewport_size,
IntRect* visible_rect) const {
if (!viewport_override_)
void DevToolsEmulator::OverrideVisibleRect(
const IntSize& viewport_size,
IntRect* visible_rect_in_frame) const {
WebLocalFrameImpl* frame = web_view_->MainFrameImpl();
if (!viewport_override_ || !frame)
return;
FloatSize scaled_viewport_size(viewport_size);
scaled_viewport_size.Scale(1. / viewport_override_->scale);
*visible_rect = EnclosingIntRect(
IntRect visible_rect_in_document = EnclosingIntRect(
FloatRect(viewport_override_->position, scaled_viewport_size));
*visible_rect_in_frame =
frame->GetFrameView()->DocumentToFrame(visible_rect_in_document);
}
float DevToolsEmulator::InputEventsScaleForEmulation() {
......
Tests that screenshot works with clip
{"x":0,"y":15018,"width":54,"height":54}
{
id : <number>
result : {
data : iVBORw0KGgoAAAANSUhEUgAAADYAAAA2CAYAAACMRWrdAAAAAXNSR0IArs4c6QAAAG9JREFUaIHt2jEKgDAQAMFEfHh+roXgCxRZmalS3pIrb45xHOOHtq8HeMt+v9b8cIwHrWsBf/tjwmqE1QirEVYjrEZYjbAaYTXCaoTVCKsRViOsRliNsBphNcJqhNUIqxFWI6xGWI2wGmE1001wzAmiFwZpJEBbewAAAABJRU5ErkJggg==
}
sessionId : <string>
}
(async function(testRunner) {
var {page, session, dp} = await testRunner.startHTML(`
<style>div.above {
border: 2px solid blue;
background: red;
height: 15000px;
}
div.to-screenshot {
border: 2px solid blue;
background: green;
width: 50px;
height: 50px;
}
body {
margin: 0;
}
</style>
<div style="height: 14px">oooo</div>
<div class="above"></div>
<div class="to-screenshot"></div>`, 'Tests that screenshot works with clip');
const json = await session.evaluate(`
(() => {
const div = document.querySelector('div.to-screenshot');
const box = div.getBoundingClientRect();
window.scrollTo(0, 15000);
return JSON.stringify({x: box.left, y: box.top, width: box.width, height: box.height});
})()
`);
testRunner.log(json);
const clip = JSON.parse(json);
testRunner.log(await dp.Page.captureScreenshot({format: 'png', clip: {...clip, scale: 1}}));
testRunner.completeTest();
})
\ No newline at end of file
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