[unseasoned-pdf] Add scrolling mechanism to the non-Pepper plugin.
Implement SkiaGraphics::Scroll() which paints the scrolling result onto SkiaGraphics before repainting the plugin. Also repaint the whole plugin area when the snapshot is updated or when the plugin area is resized. Change-Id: I71ebdd17e313d561968930414cd84868c66e563a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2782840 Commit-Queue: Hui Yingst <nigi@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org> Reviewed-by: Daniel Hosseinian <dhoss@chromium.org> Reviewed-by: Scott Violet <sky@chromium.org> Cr-Commit-Position: refs/heads/master@{#868190}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
9e240057ce
commit
b2b76b8c08
@ -252,6 +252,7 @@ if (enable_pdf) {
|
|||||||
"//third_party/blink/public:blink",
|
"//third_party/blink/public:blink",
|
||||||
"//ui/base",
|
"//ui/base",
|
||||||
"//ui/base/cursor/mojom:cursor_type",
|
"//ui/base/cursor/mojom:cursor_type",
|
||||||
|
"//ui/gfx",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
pdf/DEPS
5
pdf/DEPS
@ -15,10 +15,7 @@ include_rules = [
|
|||||||
"+ui/base/text/bytes_formatting.h",
|
"+ui/base/text/bytes_formatting.h",
|
||||||
"+ui/base/window_open_disposition.h",
|
"+ui/base/window_open_disposition.h",
|
||||||
"+ui/events/keycodes/keyboard_codes.h",
|
"+ui/events/keycodes/keyboard_codes.h",
|
||||||
"+ui/gfx/geometry",
|
"+ui/gfx",
|
||||||
"+ui/gfx/range/range.h",
|
|
||||||
"+ui/gfx/skia_util.h",
|
|
||||||
"+ui/gfx/test/gfx_util.h",
|
|
||||||
"+v8/include/v8.h"
|
"+v8/include/v8.h"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -311,7 +311,7 @@ std::unique_ptr<Graphics> PdfViewWebPlugin::CreatePaintGraphics(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool PdfViewWebPlugin::BindPaintGraphics(Graphics& graphics) {
|
bool PdfViewWebPlugin::BindPaintGraphics(Graphics& graphics) {
|
||||||
NOTIMPLEMENTED_LOG_ONCE();
|
InvalidatePluginContainer();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,6 +364,7 @@ void PdfViewWebPlugin::UpdateSnapshot(sk_sp<SkImage> snapshot) {
|
|||||||
.set_image(std::move(snapshot), cc::PaintImage::GetNextContentId())
|
.set_image(std::move(snapshot), cc::PaintImage::GetNextContentId())
|
||||||
.set_id(cc::PaintImage::GetNextId())
|
.set_id(cc::PaintImage::GetNextId())
|
||||||
.TakePaintImage();
|
.TakePaintImage();
|
||||||
|
InvalidateRectInPluginContainer(gfx::Rect(plugin_size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
base::WeakPtr<PdfViewPluginBase> PdfViewWebPlugin::GetWeakPtr() {
|
base::WeakPtr<PdfViewPluginBase> PdfViewWebPlugin::GetWeakPtr() {
|
||||||
@ -456,4 +457,19 @@ void PdfViewWebPlugin::OnViewportChanged(const gfx::Rect& view_rect,
|
|||||||
// print preview plugin.
|
// print preview plugin.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PdfViewWebPlugin::InvalidatePluginContainer() {
|
||||||
|
DCHECK(container_);
|
||||||
|
|
||||||
|
container_->Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdfViewWebPlugin::InvalidateRectInPluginContainer(const gfx::Rect& rect) {
|
||||||
|
DCHECK(container_);
|
||||||
|
|
||||||
|
if (plugin_size().IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
container_->InvalidateRect(rect);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace chrome_pdf
|
} // namespace chrome_pdf
|
||||||
|
@ -129,6 +129,14 @@ class PdfViewWebPlugin final : public PdfViewPluginBase,
|
|||||||
|
|
||||||
void OnViewportChanged(const gfx::Rect& view_rect, float new_device_scale);
|
void OnViewportChanged(const gfx::Rect& view_rect, float new_device_scale);
|
||||||
|
|
||||||
|
// Invalidates the entire web plugin container and schedules a paint of the
|
||||||
|
// page in it.
|
||||||
|
void InvalidatePluginContainer();
|
||||||
|
|
||||||
|
// Schedules a paint of the page of a given region in the web plugin
|
||||||
|
// container. The coordinates are relative to the top-left of the container.
|
||||||
|
void InvalidateRectInPluginContainer(const gfx::Rect& rect);
|
||||||
|
|
||||||
blink::WebPluginParams initial_params_;
|
blink::WebPluginParams initial_params_;
|
||||||
blink::WebPluginContainer* container_ = nullptr;
|
blink::WebPluginContainer* container_ = nullptr;
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "base/callback.h"
|
#include "base/callback.h"
|
||||||
@ -22,6 +23,7 @@
|
|||||||
#include "ppapi/cpp/point.h"
|
#include "ppapi/cpp/point.h"
|
||||||
#include "ppapi/cpp/rect.h"
|
#include "ppapi/cpp/rect.h"
|
||||||
#include "third_party/skia/include/core/SkCanvas.h"
|
#include "third_party/skia/include/core/SkCanvas.h"
|
||||||
|
#include "ui/gfx/blit.h"
|
||||||
#include "ui/gfx/geometry/rect.h"
|
#include "ui/gfx/geometry/rect.h"
|
||||||
#include "ui/gfx/geometry/size.h"
|
#include "ui/gfx/geometry/size.h"
|
||||||
#include "ui/gfx/geometry/vector2d.h"
|
#include "ui/gfx/geometry/vector2d.h"
|
||||||
@ -100,7 +102,11 @@ SkiaGraphics::SkiaGraphics(Client* client, const gfx::Size& size)
|
|||||||
SkiaGraphics::~SkiaGraphics() = default;
|
SkiaGraphics::~SkiaGraphics() = default;
|
||||||
|
|
||||||
bool SkiaGraphics::Flush(ResultCallback callback) {
|
bool SkiaGraphics::Flush(ResultCallback callback) {
|
||||||
client_->UpdateSnapshot(skia_graphics_->makeImageSnapshot());
|
sk_sp<SkImage> snapshot = skia_graphics_->makeImageSnapshot();
|
||||||
|
skia_graphics_->getCanvas()->drawImage(
|
||||||
|
snapshot.get(), /*x=*/0, /*y=*/0, SkSamplingOptions(), /*paint=*/nullptr);
|
||||||
|
|
||||||
|
client_->UpdateSnapshot(std::move(snapshot));
|
||||||
|
|
||||||
base::SequencedTaskRunnerHandle::Get()->PostTask(
|
base::SequencedTaskRunnerHandle::Get()->PostTask(
|
||||||
FROM_HERE, base::BindOnce(std::move(callback), 0));
|
FROM_HERE, base::BindOnce(std::move(callback), 0));
|
||||||
@ -115,7 +121,14 @@ void SkiaGraphics::PaintImage(const Image& image, const gfx::Rect& src_rect) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SkiaGraphics::Scroll(const gfx::Rect& clip, const gfx::Vector2d& amount) {
|
void SkiaGraphics::Scroll(const gfx::Rect& clip, const gfx::Vector2d& amount) {
|
||||||
NOTIMPLEMENTED_LOG_ONCE();
|
// If we are being asked to scroll by more than the graphics' rect size, just
|
||||||
|
// ignore the scroll command.
|
||||||
|
if (std::abs(amount.x()) >= skia_graphics_->width() ||
|
||||||
|
std::abs(amount.y()) >= skia_graphics_->height()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::ScrollCanvas(skia_graphics_->getCanvas(), clip, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkiaGraphics::SetScale(float scale) {
|
void SkiaGraphics::SetScale(float scale) {
|
||||||
|
@ -52,6 +52,20 @@ SkBitmap GenerateExpectedBitmap(const SkISize& graphics_size,
|
|||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Creates a nonuniform SkBitmap with given `width` and `height`, such
|
||||||
|
// that scrolling will cause a noticeable change to the bitmap. Returns an
|
||||||
|
// empty SkBitmap if either `width` or `height` is less than 4.
|
||||||
|
SkBitmap CreateNonuniformBitmap(int width, int height) {
|
||||||
|
if (width < 4 || height < 4)
|
||||||
|
return SkBitmap();
|
||||||
|
|
||||||
|
SkBitmap bitmap = CreateN32PremulSkBitmap(SkISize::Make(width, height));
|
||||||
|
bitmap.eraseColor(SK_ColorRED);
|
||||||
|
bitmap.erase(SK_ColorGREEN, {1, 1, width - 1, height - 2});
|
||||||
|
bitmap.erase(SK_ColorBLACK, {2, 3, 1, 2});
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class SkiaGraphicsTest : public testing::Test {
|
class SkiaGraphicsTest : public testing::Test {
|
||||||
@ -93,6 +107,43 @@ class SkiaGraphicsTest : public testing::Test {
|
|||||||
base::test::TaskEnvironment task_environment_;
|
base::test::TaskEnvironment task_environment_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SkiaGraphicsScrollTest : public SkiaGraphicsTest {
|
||||||
|
protected:
|
||||||
|
static constexpr gfx::Rect kGraphicsRect = gfx::Rect(4, 5);
|
||||||
|
|
||||||
|
// Initializes `initial_bitmap_` and `graphics_` before scrolling tests.
|
||||||
|
void SetUp() override {
|
||||||
|
graphics_ = SkiaGraphics::Create(&client_, kGraphicsRect.size());
|
||||||
|
ASSERT_TRUE(graphics_);
|
||||||
|
|
||||||
|
// Paint a nonuniform SkBitmap to graphics.
|
||||||
|
initial_bitmap_ =
|
||||||
|
CreateNonuniformBitmap(kGraphicsRect.width(), kGraphicsRect.height());
|
||||||
|
graphics_->PaintImage(Image(initial_bitmap_), kGraphicsRect);
|
||||||
|
graphics_->Flush(base::DoNothing());
|
||||||
|
SkBitmap initial_snapshot;
|
||||||
|
ASSERT_TRUE(client_.snapshot->asLegacyBitmap(&initial_snapshot));
|
||||||
|
ASSERT_TRUE(cc::MatchesBitmap(initial_snapshot, initial_bitmap_,
|
||||||
|
cc::ExactPixelComparator(false)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resets the canvas with `initial_bitmap_`, then scrolls it by
|
||||||
|
// `scroll_amount`.
|
||||||
|
void ResetAndScroll(const gfx::Vector2d& scroll_amount) {
|
||||||
|
if (!graphics_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
graphics_->PaintImage(Image(initial_bitmap_), kGraphicsRect);
|
||||||
|
graphics_->Scroll(kGraphicsRect, scroll_amount);
|
||||||
|
graphics_->Flush(base::DoNothing());
|
||||||
|
}
|
||||||
|
|
||||||
|
SkBitmap initial_bitmap_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// static
|
||||||
|
constexpr gfx::Rect SkiaGraphicsScrollTest::kGraphicsRect;
|
||||||
|
|
||||||
TEST_F(SkiaGraphicsTest, Flush) {
|
TEST_F(SkiaGraphicsTest, Flush) {
|
||||||
graphics_ = SkiaGraphics::Create(&client_, gfx::Size(20, 20));
|
graphics_ = SkiaGraphics::Create(&client_, gfx::Size(20, 20));
|
||||||
ASSERT_TRUE(graphics_);
|
ASSERT_TRUE(graphics_);
|
||||||
@ -138,4 +189,48 @@ TEST_F(SkiaGraphicsTest, PaintImage) {
|
|||||||
params.paint_rect, params.overlapped_rect);
|
params.paint_rect, params.overlapped_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SkiaGraphicsScrollTest, InvalidScroll) {
|
||||||
|
static constexpr gfx::Vector2d kNoOpScrollAmounts[] = {
|
||||||
|
// Scroll to the edge of the graphics rect.
|
||||||
|
{kGraphicsRect.width(), 0},
|
||||||
|
{-kGraphicsRect.width(), 0},
|
||||||
|
{0, kGraphicsRect.height()},
|
||||||
|
{0, -kGraphicsRect.height()},
|
||||||
|
// Scroll outside the graphics rect.
|
||||||
|
{kGraphicsRect.width() + 1, 0},
|
||||||
|
{-(kGraphicsRect.width() + 2), 0},
|
||||||
|
{0, kGraphicsRect.height() + 3},
|
||||||
|
{0, -(kGraphicsRect.height() + 4)},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& no_op_amount : kNoOpScrollAmounts) {
|
||||||
|
ResetAndScroll(no_op_amount);
|
||||||
|
SkBitmap snapshot;
|
||||||
|
ASSERT_TRUE(client_.snapshot->asLegacyBitmap(&snapshot));
|
||||||
|
EXPECT_TRUE(cc::MatchesBitmap(snapshot, initial_bitmap_,
|
||||||
|
cc::ExactPixelComparator(false)))
|
||||||
|
<< "SkBitmap comparison failed for scroll amount of "
|
||||||
|
<< no_op_amount.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SkiaGraphicsScrollTest, Scroll) {
|
||||||
|
static constexpr gfx::Vector2d kValidScrollAmounts[] = {
|
||||||
|
{1, 0},
|
||||||
|
{-2, 0},
|
||||||
|
{0, 3},
|
||||||
|
{0, -3},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& valid_amount : kValidScrollAmounts) {
|
||||||
|
ResetAndScroll(valid_amount);
|
||||||
|
SkBitmap snapshot;
|
||||||
|
ASSERT_TRUE(client_.snapshot->asLegacyBitmap(&snapshot));
|
||||||
|
EXPECT_FALSE(cc::MatchesBitmap(snapshot, initial_bitmap_,
|
||||||
|
cc::ExactPixelComparator(false)))
|
||||||
|
<< "The scroll amount of " << valid_amount.ToString()
|
||||||
|
<< " failed to change the snapshot of `graphics_`";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace chrome_pdf
|
} // namespace chrome_pdf
|
||||||
|
Reference in New Issue
Block a user