[PDF Ink Signatures] Move Ink thumbnail code into PdfInkModule
Currently, PdfInkModule asks PdfViewWebPlugin to generate the Ink thumbnail. PdfViewWebPlugin does some setup, then turns around and ask PdfInkModule to draw the thumbnail. Rearrange the code so that PdfInkModule does the majority of the work. Now the only interaction with PdfViewWebPlugin is to get the thumbnail size. When https://crrev.com/1351738 added the Ink thumbnail code, it was not possible for PdfInkModule to call PdfViewWebPluginClient::PostMessage() without doing additional work. Since then, https://crrev.com/1372446 plumbed PostMessage() to PdfInkModule, so this CL takes advantage of that to centralize the Ink thumbnail code. Change-Id: I0c5bf9276e6e1fca047805e49accb8a43a6a92a6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6288546 Reviewed-by: Alan Screen <awscreen@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org> Cr-Commit-Position: refs/heads/main@{#1423286}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
e35d6616b7
commit
b6cebbe23f
@ -171,6 +171,38 @@ void PdfInkModule::Draw(SkCanvas& canvas) {
|
||||
}
|
||||
}
|
||||
|
||||
void PdfInkModule::GenerateAndSendInkThumbnail(
|
||||
int page_index,
|
||||
const gfx::Size& thumbnail_size) {
|
||||
CHECK(!thumbnail_size.IsEmpty());
|
||||
|
||||
auto info = SkImageInfo::Make(thumbnail_size.width(), thumbnail_size.height(),
|
||||
kRGBA_8888_SkColorType, kUnpremul_SkAlphaType);
|
||||
const size_t alloc_size = info.computeMinByteSize();
|
||||
CHECK(!SkImageInfo::ByteSizeOverflowed(alloc_size));
|
||||
std::vector<uint8_t> image_data(alloc_size);
|
||||
|
||||
SkBitmap sk_bitmap;
|
||||
sk_bitmap.installPixels(info, image_data.data(), info.minRowBytes());
|
||||
SkCanvas canvas(sk_bitmap);
|
||||
if (!DrawThumbnail(canvas, page_index)) {
|
||||
return;
|
||||
}
|
||||
|
||||
base::Value::Dict message;
|
||||
message.Set("type", "updateInk2Thumbnail");
|
||||
message.Set("pageNumber", page_index + 1);
|
||||
message.Set("imageData", std::move(image_data));
|
||||
message.Set("width", thumbnail_size.width());
|
||||
message.Set("height", thumbnail_size.height());
|
||||
client_->PostMessage(std::move(message));
|
||||
}
|
||||
|
||||
void PdfInkModule::GenerateAndSendInkThumbnailInternal(int page_index) {
|
||||
return GenerateAndSendInkThumbnail(page_index,
|
||||
client_->GetThumbnailSize(page_index));
|
||||
}
|
||||
|
||||
bool PdfInkModule::DrawThumbnail(SkCanvas& canvas, int page_index) {
|
||||
auto it = strokes_.find(page_index);
|
||||
if (it == strokes_.end() || it->second.empty()) {
|
||||
@ -615,7 +647,7 @@ bool PdfInkModule::FinishStroke(const gfx::PointF& position,
|
||||
}
|
||||
|
||||
client_->StrokeFinished();
|
||||
client_->UpdateThumbnail(state.page_index);
|
||||
GenerateAndSendInkThumbnailInternal(state.page_index);
|
||||
|
||||
bool undo_redo_success = undo_redo_model_.FinishDraw();
|
||||
CHECK(undo_redo_success);
|
||||
@ -709,7 +741,7 @@ bool PdfInkModule::FinishEraseStroke(const gfx::PointF& position,
|
||||
if (!state.page_indices_with_erasures.empty()) {
|
||||
client_->StrokeFinished();
|
||||
for (int page_index : state.page_indices_with_erasures) {
|
||||
client_->UpdateThumbnail(page_index);
|
||||
GenerateAndSendInkThumbnailInternal(page_index);
|
||||
}
|
||||
|
||||
ReportEraseStroke(eraser_size_, tool_type);
|
||||
@ -1174,7 +1206,7 @@ void PdfInkModule::ApplyUndoRedoCommandsHelper(
|
||||
}
|
||||
|
||||
for (int page_index : page_indices_with_thumbnail_updates) {
|
||||
client_->UpdateThumbnail(page_index);
|
||||
GenerateAndSendInkThumbnailInternal(page_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,10 +140,12 @@ class PdfInkModule {
|
||||
// stroke state with non-empty `drawing_stroke_state().inputs`.
|
||||
void Draw(SkCanvas& canvas);
|
||||
|
||||
// Draws `strokes_` for `page_index` into `canvas`. Here, `canvas` only covers
|
||||
// the region for the page at `page_index`, so this only draws strokes for
|
||||
// that page, regardless of page visibility.
|
||||
bool DrawThumbnail(SkCanvas& canvas, int page_index);
|
||||
// Generates a thumbnail of `thumbnail_size` for the page at `page_index`
|
||||
// using DrawThumbnail(). Sends the result to the WebUI if successful.
|
||||
// Otherwise, do not send anything to the WebUI.
|
||||
// `thumbnail_size` must be non-empty.
|
||||
void GenerateAndSendInkThumbnail(int page_index,
|
||||
const gfx::Size& thumbnail_size);
|
||||
|
||||
// Gets an iterator for the visible strokes across all pages.
|
||||
// Modifying the set of visible strokes while using the iterator is not
|
||||
@ -392,6 +394,16 @@ class PdfInkModule {
|
||||
|
||||
void MaybeSetDrawingBrushAndCursor();
|
||||
|
||||
// Helper that calls GenerateAndSendInkThumbnail() without needing to specify
|
||||
// the thumbnail size. This helper determines the size by asking
|
||||
// PdfInkModuleClient.
|
||||
void GenerateAndSendInkThumbnailInternal(int page_index);
|
||||
|
||||
// Draws `strokes_` for `page_index` into `canvas`. Here, `canvas` only covers
|
||||
// the region for the page at `page_index`, so this only draws strokes for
|
||||
// that page, regardless of page visibility.
|
||||
bool DrawThumbnail(SkCanvas& canvas, int page_index);
|
||||
|
||||
const raw_ref<PdfInkModuleClient> client_;
|
||||
|
||||
bool enabled_ = false;
|
||||
|
@ -52,6 +52,10 @@ class PdfInkModuleClient {
|
||||
// non-negative page index returned from `VisiblePageIndexFromPoint()`.
|
||||
virtual gfx::Rect GetPageContentsRect(int page_index) = 0;
|
||||
|
||||
// Gets the thumbnail size for `page_index`. The size must be non-empty for
|
||||
// any valid page index.
|
||||
virtual gfx::Size GetThumbnailSize(int page_index) = 0;
|
||||
|
||||
// Gets the offset within the rendering viewport to where the page images
|
||||
// will be drawn. Since the offset is a location within the viewport, it
|
||||
// must always contain non-negative values. Values are in scaled CSS
|
||||
@ -103,9 +107,6 @@ class PdfInkModuleClient {
|
||||
virtual void UpdateStrokeActive(int page_index, InkStrokeId id, bool active) {
|
||||
}
|
||||
|
||||
// Asks the client to update the thumbnail for `page_index`.
|
||||
virtual void UpdateThumbnail(int page_index) {}
|
||||
|
||||
// Returns the 0-based page index for the given `point` if it is on a
|
||||
// visible page, or -1 if `point` is not on a visible page.
|
||||
virtual int VisiblePageIndexFromPoint(const gfx::PointF& point) = 0;
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "pdf/pdfium/pdfium_ink_reader.h"
|
||||
#include "pdf/test/mouse_event_builder.h"
|
||||
#include "pdf/test/pdf_ink_test_helpers.h"
|
||||
#include "pdf/ui/thumbnail.h"
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "third_party/blink/public/common/input/web_mouse_event.h"
|
||||
@ -251,6 +252,14 @@ class FakeClient : public PdfInkModuleClient {
|
||||
|
||||
PageOrientation GetOrientation() const override { return orientation_; }
|
||||
|
||||
gfx::Size GetThumbnailSize(int page_index) override {
|
||||
CHECK_GE(page_index, 0);
|
||||
CHECK_LT(static_cast<size_t>(page_index), page_layouts_.size());
|
||||
Thumbnail thumbnail(page_layouts_[page_index].size(),
|
||||
/*device_pixel_ratio=*/1);
|
||||
return thumbnail.image_size();
|
||||
}
|
||||
|
||||
gfx::Vector2dF GetViewportOriginOffset() override {
|
||||
return viewport_origin_offset_;
|
||||
}
|
||||
@ -297,10 +306,6 @@ class FakeClient : public PdfInkModuleClient {
|
||||
(int page_index, InkStrokeId id, bool active),
|
||||
(override));
|
||||
|
||||
void UpdateThumbnail(int page_index) override {
|
||||
updated_thumbnail_page_indices_.push_back(page_index);
|
||||
}
|
||||
|
||||
int VisiblePageIndexFromPoint(const gfx::PointF& point) override {
|
||||
for (size_t i = 0; i < page_layouts_.size(); ++i) {
|
||||
if (IsPageVisible(i) && page_layouts_[i].Contains(point)) {
|
||||
@ -314,10 +319,6 @@ class FakeClient : public PdfInkModuleClient {
|
||||
|
||||
int stroke_finished_count() const { return stroke_finished_count_; }
|
||||
|
||||
const std::vector<int>& updated_thumbnail_page_indices() const {
|
||||
return updated_thumbnail_page_indices_;
|
||||
}
|
||||
|
||||
const std::vector<gfx::Rect>& invalidations() const { return invalidations_; }
|
||||
|
||||
// Provide the sequence of pages and the coordinates and dimensions for how
|
||||
@ -349,7 +350,6 @@ class FakeClient : public PdfInkModuleClient {
|
||||
|
||||
private:
|
||||
int stroke_finished_count_ = 0;
|
||||
std::vector<int> updated_thumbnail_page_indices_;
|
||||
std::vector<gfx::RectF> page_layouts_;
|
||||
std::set<int> visible_page_indices_;
|
||||
PageOrientation orientation_ = PageOrientation::kOriginal;
|
||||
@ -750,6 +750,24 @@ class PdfInkModuleStrokeTest : public PdfInkModuleTest {
|
||||
static constexpr gfx::PointF kMousePoints[] = {
|
||||
kMouseDownPoint, kMouseMovePoint, kMouseUpPoint};
|
||||
|
||||
// PdfInkModuleTest:
|
||||
void SetUp() override {
|
||||
PdfInkModuleTest::SetUp();
|
||||
|
||||
EXPECT_CALL(client(), PostMessage)
|
||||
.WillRepeatedly([&](const base::Value::Dict& dict) {
|
||||
const std::string* type = dict.FindString("type");
|
||||
ASSERT_TRUE(type);
|
||||
if (*type != "updateInk2Thumbnail") {
|
||||
return;
|
||||
}
|
||||
|
||||
std::optional<int> page_number = dict.FindInt("pageNumber");
|
||||
ASSERT_TRUE(page_number.has_value());
|
||||
updated_thumbnail_page_indices_.push_back(page_number.value() - 1);
|
||||
});
|
||||
}
|
||||
|
||||
void InitializeSimpleSinglePageBasicLayout() {
|
||||
// Single page layout that matches visible area.
|
||||
constexpr gfx::RectF kPage(0.0f, 0.0f, 50.0f, 60.0f);
|
||||
@ -992,6 +1010,10 @@ class PdfInkModuleStrokeTest : public PdfInkModuleTest {
|
||||
testing::Mock::VerifyAndClearExpectations(this);
|
||||
}
|
||||
|
||||
const std::vector<int>& updated_thumbnail_page_indices() const {
|
||||
return updated_thumbnail_page_indices_;
|
||||
}
|
||||
|
||||
private:
|
||||
void ApplyStrokeWithMouseAtPointsMaybeHandled(
|
||||
const gfx::PointF& mouse_down_point,
|
||||
@ -1062,14 +1084,14 @@ class PdfInkModuleStrokeTest : public PdfInkModuleTest {
|
||||
|
||||
void ValidateRunStrokeCheckTest(bool expect_stroke_success) {
|
||||
EXPECT_EQ(expect_stroke_success ? 1 : 0, client().stroke_finished_count());
|
||||
const std::vector<int>& updated_thumbnail_page_indices =
|
||||
client().updated_thumbnail_page_indices();
|
||||
if (expect_stroke_success) {
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0));
|
||||
} else {
|
||||
EXPECT_TRUE(updated_thumbnail_page_indices.empty());
|
||||
EXPECT_TRUE(updated_thumbnail_page_indices().empty());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> updated_thumbnail_page_indices_;
|
||||
};
|
||||
|
||||
TEST_F(PdfInkModuleStrokeTest, NoAnnotationWithMouseIfNotEnabled) {
|
||||
@ -1479,9 +1501,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStroke) {
|
||||
VisibleStrokeInputPositions(),
|
||||
ElementsAre(Pair(0, ElementsAre(ElementsAreArray(kMousePoints)))));
|
||||
EXPECT_EQ(1, client().stroke_finished_count());
|
||||
const std::vector<int>& updated_thumbnail_page_indices =
|
||||
client().updated_thumbnail_page_indices();
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0));
|
||||
|
||||
// Stroke with the eraser tool.
|
||||
SelectEraserToolOfSize(3.0f);
|
||||
@ -1491,7 +1511,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStroke) {
|
||||
EXPECT_TRUE(VisibleStrokeInputPositions().empty());
|
||||
// Erasing counts as another stroke action.
|
||||
EXPECT_EQ(2, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0));
|
||||
|
||||
// Stroke again. The stroke that have already been erased should stay erased.
|
||||
ApplyStrokeWithMouseAtMouseDownPoint();
|
||||
@ -1500,7 +1520,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStroke) {
|
||||
EXPECT_TRUE(VisibleStrokeInputPositions().empty());
|
||||
// Nothing got erased, so the count stays at 2.
|
||||
EXPECT_EQ(2, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0));
|
||||
}
|
||||
|
||||
TEST_F(PdfInkModuleStrokeTest, EraseOnPageWithoutStrokes) {
|
||||
@ -1518,7 +1538,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseOnPageWithoutStrokes) {
|
||||
// called.
|
||||
EXPECT_TRUE(VisibleStrokeInputPositions().empty());
|
||||
EXPECT_EQ(0, client().stroke_finished_count());
|
||||
EXPECT_TRUE(client().updated_thumbnail_page_indices().empty());
|
||||
EXPECT_TRUE(updated_thumbnail_page_indices().empty());
|
||||
}
|
||||
|
||||
TEST_F(PdfInkModuleStrokeTest, EraseStrokeEntirelyOffPage) {
|
||||
@ -1530,9 +1550,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokeEntirelyOffPage) {
|
||||
VisibleStrokeInputPositions(),
|
||||
ElementsAre(Pair(0, ElementsAre(ElementsAreArray(kMousePoints)))));
|
||||
EXPECT_EQ(1, client().stroke_finished_count());
|
||||
const std::vector<int>& updated_thumbnail_page_indices =
|
||||
client().updated_thumbnail_page_indices();
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0));
|
||||
|
||||
// Stroke with the eraser tool outside of the page.
|
||||
SelectEraserToolOfSize(3.0f);
|
||||
@ -1546,7 +1564,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokeEntirelyOffPage) {
|
||||
VisibleStrokeInputPositions(),
|
||||
ElementsAre(Pair(0, ElementsAre(ElementsAreArray(kMousePoints)))));
|
||||
EXPECT_EQ(1, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0));
|
||||
}
|
||||
|
||||
TEST_F(PdfInkModuleStrokeTest, EraseStrokeErasesTwoStrokes) {
|
||||
@ -1568,9 +1586,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokeErasesTwoStrokes) {
|
||||
Pair(0, ElementsAre(ElementsAreArray(kMousePoints), kStroke2Matcher)));
|
||||
EXPECT_THAT(VisibleStrokeInputPositions(), kVisibleStrokesMatcher);
|
||||
EXPECT_EQ(2, client().stroke_finished_count());
|
||||
const std::vector<int>& updated_thumbnail_page_indices =
|
||||
client().updated_thumbnail_page_indices();
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0));
|
||||
|
||||
// Stroke with the eraser tool at `kMouseMovePoint`, where it should
|
||||
// intersect with both strokes, but does not because InkStrokeModeler modeled
|
||||
@ -1583,7 +1599,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokeErasesTwoStrokes) {
|
||||
// the strokes.
|
||||
EXPECT_THAT(VisibleStrokeInputPositions(), kVisibleStrokesMatcher);
|
||||
EXPECT_EQ(2, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0));
|
||||
|
||||
// Stroke with the eraser tool again at `kMousePoints`, but now with a much
|
||||
// bigger eraser size. This will actually intersect with both strokes.
|
||||
@ -1597,7 +1613,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokeErasesTwoStrokes) {
|
||||
// Check that there are now no visible strokes.
|
||||
EXPECT_TRUE(VisibleStrokeInputPositions().empty());
|
||||
EXPECT_EQ(3, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0, 0));
|
||||
}
|
||||
|
||||
TEST_F(PdfInkModuleStrokeTest, EraseStrokesAcrossTwoPages) {
|
||||
@ -1607,9 +1623,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokesAcrossTwoPages) {
|
||||
// Start out without any strokes.
|
||||
EXPECT_TRUE(StrokeInputPositions().empty());
|
||||
EXPECT_EQ(0, client().stroke_finished_count());
|
||||
const std::vector<int>& updated_thumbnail_page_indices =
|
||||
client().updated_thumbnail_page_indices();
|
||||
EXPECT_TRUE(updated_thumbnail_page_indices.empty());
|
||||
EXPECT_TRUE(updated_thumbnail_page_indices().empty());
|
||||
|
||||
ExpectStrokesAdded(/*strokes_affected=*/2);
|
||||
ExpectNoUpdateStrokeActive();
|
||||
@ -1621,7 +1635,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokesAcrossTwoPages) {
|
||||
kTwoPageVerticalLayoutPoint3InsidePage0);
|
||||
EXPECT_THAT(StrokeInputPositions(), ElementsAre(Pair(0, SizeIs(1))));
|
||||
EXPECT_EQ(1, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0));
|
||||
|
||||
// A stroke in the second page generates a stroke only for that page.
|
||||
ApplyStrokeWithMouseAtPoints(
|
||||
@ -1631,7 +1645,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokesAcrossTwoPages) {
|
||||
EXPECT_THAT(StrokeInputPositions(),
|
||||
ElementsAre(Pair(0, SizeIs(1)), Pair(1, SizeIs(1))));
|
||||
EXPECT_EQ(2, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 1));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 1));
|
||||
|
||||
// Erasing across the two pages should erase everything.
|
||||
SelectEraserToolOfSize(3.0f);
|
||||
@ -1645,7 +1659,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokesAcrossTwoPages) {
|
||||
kTwoPageVerticalLayoutPoint3InsidePage1);
|
||||
EXPECT_TRUE(VisibleStrokeInputPositions().empty());
|
||||
EXPECT_EQ(3, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 1, 0, 1));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 1, 0, 1));
|
||||
}
|
||||
|
||||
TEST_F(PdfInkModuleStrokeTest, EraseStrokePageExitAndReentry) {
|
||||
@ -1668,9 +1682,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokePageExitAndReentry) {
|
||||
ElementsAreArray(
|
||||
kTwoPageVerticalLayoutPageExitAndReentrySegment2)))));
|
||||
EXPECT_EQ(1, client().stroke_finished_count());
|
||||
const std::vector<int>& updated_thumbnail_page_indices =
|
||||
client().updated_thumbnail_page_indices();
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0));
|
||||
|
||||
// Select the eraser tool and call ApplyStrokeWithMouseAtPoints() again with
|
||||
// the same arguments.
|
||||
@ -1691,7 +1703,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokePageExitAndReentry) {
|
||||
EXPECT_TRUE(VisibleStrokeInputPositions().empty());
|
||||
// Erasing counts as another stroke action.
|
||||
EXPECT_EQ(2, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0));
|
||||
}
|
||||
|
||||
TEST_F(PdfInkModuleStrokeTest, EraseStrokeWithTouch) {
|
||||
@ -1703,9 +1715,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokeWithTouch) {
|
||||
VisibleStrokeInputPositions(),
|
||||
ElementsAre(Pair(0, ElementsAre(ElementsAreArray(kMousePoints)))));
|
||||
EXPECT_EQ(1, client().stroke_finished_count());
|
||||
const std::vector<int>& updated_thumbnail_page_indices =
|
||||
client().updated_thumbnail_page_indices();
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0));
|
||||
|
||||
// Stroke with the eraser tool.
|
||||
SelectEraserToolOfSize(3.0f);
|
||||
@ -1720,7 +1730,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokeWithTouch) {
|
||||
EXPECT_TRUE(VisibleStrokeInputPositions().empty());
|
||||
// Erasing counts as another stroke action.
|
||||
EXPECT_EQ(2, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0));
|
||||
|
||||
// Stroke again. The stroke that have already been erased should stay erased.
|
||||
ApplyStrokeWithTouchAtPoints(base::span_from_ref(kMouseDownPoint),
|
||||
@ -1731,7 +1741,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokeWithTouch) {
|
||||
EXPECT_TRUE(VisibleStrokeInputPositions().empty());
|
||||
// Nothing got erased, so the count stays at 2.
|
||||
EXPECT_EQ(2, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0));
|
||||
|
||||
// Stroke again with the mouse gets the same results.
|
||||
ApplyStrokeWithMouseAtMouseDownPoint();
|
||||
@ -1740,7 +1750,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokeWithTouch) {
|
||||
EXPECT_TRUE(VisibleStrokeInputPositions().empty());
|
||||
// Nothing got erased, so the count stays at 2.
|
||||
EXPECT_EQ(2, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0));
|
||||
}
|
||||
|
||||
TEST_F(PdfInkModuleStrokeTest, EraseStrokeWithPen) {
|
||||
@ -1752,9 +1762,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokeWithPen) {
|
||||
VisibleStrokeInputPositions(),
|
||||
ElementsAre(Pair(0, ElementsAre(ElementsAreArray(kMousePoints)))));
|
||||
EXPECT_EQ(1, client().stroke_finished_count());
|
||||
const std::vector<int>& updated_thumbnail_page_indices =
|
||||
client().updated_thumbnail_page_indices();
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0));
|
||||
|
||||
// Stroke with the eraser tool.
|
||||
SelectEraserToolOfSize(3.0f);
|
||||
@ -1769,7 +1777,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokeWithPen) {
|
||||
EXPECT_TRUE(VisibleStrokeInputPositions().empty());
|
||||
// Erasing counts as another stroke action.
|
||||
EXPECT_EQ(2, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0));
|
||||
|
||||
// Stroke again. The stroke that have already been erased should stay erased.
|
||||
ApplyStrokeWithPenAtPoints(base::span_from_ref(kMouseDownPoint),
|
||||
@ -1780,7 +1788,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokeWithPen) {
|
||||
EXPECT_TRUE(VisibleStrokeInputPositions().empty());
|
||||
// Nothing got erased, so the count stays at 2.
|
||||
EXPECT_EQ(2, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0));
|
||||
|
||||
// Stroke again with the mouse gets the same results.
|
||||
ApplyStrokeWithMouseAtMouseDownPoint();
|
||||
@ -1789,7 +1797,7 @@ TEST_F(PdfInkModuleStrokeTest, EraseStrokeWithPen) {
|
||||
EXPECT_TRUE(VisibleStrokeInputPositions().empty());
|
||||
// Nothing got erased, so the count stays at 2.
|
||||
EXPECT_EQ(2, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0));
|
||||
}
|
||||
|
||||
TEST_F(PdfInkModuleStrokeTest, RunStrokeMissedEndEventDuringDrawing) {
|
||||
@ -2239,16 +2247,14 @@ TEST_F(PdfInkModuleUndoRedoTest, UndoRedoBasic) {
|
||||
EXPECT_THAT(VisibleStrokeInputPositions(), kMatcher);
|
||||
// RunStrokeCheckTest() performed the only stroke.
|
||||
EXPECT_EQ(1, client().stroke_finished_count());
|
||||
const std::vector<int>& updated_thumbnail_page_indices =
|
||||
client().updated_thumbnail_page_indices();
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0));
|
||||
|
||||
PerformUndo();
|
||||
EXPECT_THAT(StrokeInputPositions(), kMatcher);
|
||||
EXPECT_TRUE(VisibleStrokeInputPositions().empty());
|
||||
// Undo/redo here and below do not trigger StrokeFinished().
|
||||
EXPECT_EQ(1, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0));
|
||||
|
||||
// Spurious undo message is a no-op.
|
||||
VerifyAndClearExpectations();
|
||||
@ -2258,7 +2264,7 @@ TEST_F(PdfInkModuleUndoRedoTest, UndoRedoBasic) {
|
||||
EXPECT_THAT(StrokeInputPositions(), kMatcher);
|
||||
EXPECT_TRUE(VisibleStrokeInputPositions().empty());
|
||||
EXPECT_EQ(1, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0));
|
||||
|
||||
VerifyAndClearExpectations();
|
||||
ExpectNoStrokeAdded();
|
||||
@ -2267,7 +2273,7 @@ TEST_F(PdfInkModuleUndoRedoTest, UndoRedoBasic) {
|
||||
EXPECT_THAT(StrokeInputPositions(), kMatcher);
|
||||
EXPECT_THAT(VisibleStrokeInputPositions(), kMatcher);
|
||||
EXPECT_EQ(1, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0, 0));
|
||||
|
||||
// Spurious redo message is a no-op.
|
||||
VerifyAndClearExpectations();
|
||||
@ -2277,7 +2283,7 @@ TEST_F(PdfInkModuleUndoRedoTest, UndoRedoBasic) {
|
||||
EXPECT_THAT(StrokeInputPositions(), kMatcher);
|
||||
EXPECT_THAT(VisibleStrokeInputPositions(), kMatcher);
|
||||
EXPECT_EQ(1, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0, 0));
|
||||
}
|
||||
|
||||
TEST_F(PdfInkModuleUndoRedoTest, UndoRedoInvalidationsBasic) {
|
||||
@ -2368,9 +2374,7 @@ TEST_F(PdfInkModuleUndoRedoTest, UndoRedoAnnotationModeDisabled) {
|
||||
EXPECT_THAT(VisibleStrokeInputPositions(), kMatcher);
|
||||
// RunStrokeCheckTest() performed the only stroke.
|
||||
EXPECT_EQ(1, client().stroke_finished_count());
|
||||
const std::vector<int>& updated_thumbnail_page_indices =
|
||||
client().updated_thumbnail_page_indices();
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0));
|
||||
|
||||
// Disable annotation mode. Undo/redo should still work.
|
||||
EXPECT_TRUE(
|
||||
@ -2381,13 +2385,13 @@ TEST_F(PdfInkModuleUndoRedoTest, UndoRedoAnnotationModeDisabled) {
|
||||
EXPECT_THAT(StrokeInputPositions(), kMatcher);
|
||||
EXPECT_TRUE(VisibleStrokeInputPositions().empty());
|
||||
EXPECT_EQ(1, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0));
|
||||
|
||||
PerformRedo();
|
||||
EXPECT_THAT(StrokeInputPositions(), kMatcher);
|
||||
EXPECT_THAT(VisibleStrokeInputPositions(), kMatcher);
|
||||
EXPECT_EQ(1, client().stroke_finished_count());
|
||||
EXPECT_THAT(updated_thumbnail_page_indices, ElementsAre(0, 0, 0));
|
||||
EXPECT_THAT(updated_thumbnail_page_indices(), ElementsAre(0, 0, 0));
|
||||
}
|
||||
|
||||
TEST_F(PdfInkModuleUndoRedoTest, UndoRedoBetweenDraws) {
|
||||
|
@ -291,6 +291,11 @@ class PdfViewWebPlugin::PdfInkModuleClientImpl : public PdfInkModuleClient {
|
||||
return plugin_->engine_->GetPageContentsRect(page_index);
|
||||
}
|
||||
|
||||
gfx::Size GetThumbnailSize(int page_index) override {
|
||||
return plugin_->engine_->GetThumbnailSize(page_index,
|
||||
plugin_->device_scale_);
|
||||
}
|
||||
|
||||
gfx::Vector2dF GetViewportOriginOffset() override {
|
||||
return plugin_->available_area_.OffsetFromOrigin();
|
||||
}
|
||||
@ -365,12 +370,6 @@ class PdfViewWebPlugin::PdfInkModuleClientImpl : public PdfInkModuleClient {
|
||||
plugin_->engine_->UpdateStrokeActive(page_index, id, active);
|
||||
}
|
||||
|
||||
void UpdateThumbnail(int page_index) override {
|
||||
plugin_->GenerateAndSendInkThumbnail(
|
||||
page_index,
|
||||
plugin_->engine_->GetThumbnailSize(page_index, plugin_->device_scale_));
|
||||
}
|
||||
|
||||
int VisiblePageIndexFromPoint(const gfx::PointF& point) override {
|
||||
for (int i = 0; i < plugin_->engine_->GetNumberOfPages(); ++i) {
|
||||
if (!IsPageVisible(i)) {
|
||||
@ -2754,7 +2753,8 @@ void PdfViewWebPlugin::SendThumbnail(base::Value::Dict reply,
|
||||
|
||||
#if BUILDFLAG(ENABLE_PDF_INK2)
|
||||
if (ink_module_) {
|
||||
GenerateAndSendInkThumbnail(page_index, thumbnail.image_size());
|
||||
ink_module_->GenerateAndSendInkThumbnail(page_index,
|
||||
thumbnail.image_size());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -2777,33 +2777,6 @@ std::unique_ptr<PdfInkModule> PdfViewWebPlugin::MaybeCreatePdfInkModule(
|
||||
}
|
||||
return std::make_unique<PdfInkModule>(*client);
|
||||
}
|
||||
|
||||
void PdfViewWebPlugin::GenerateAndSendInkThumbnail(int page_index,
|
||||
const gfx::Size& size) {
|
||||
CHECK(!size.IsEmpty());
|
||||
CHECK(ink_module_);
|
||||
|
||||
auto info = SkImageInfo::Make(size.width(), size.height(),
|
||||
kRGBA_8888_SkColorType, kUnpremul_SkAlphaType);
|
||||
const size_t alloc_size = info.computeMinByteSize();
|
||||
CHECK(!SkImageInfo::ByteSizeOverflowed(alloc_size));
|
||||
std::vector<uint8_t> image_data(alloc_size);
|
||||
|
||||
SkBitmap sk_bitmap;
|
||||
sk_bitmap.installPixels(info, image_data.data(), info.minRowBytes());
|
||||
SkCanvas canvas(sk_bitmap);
|
||||
if (!ink_module_->DrawThumbnail(canvas, page_index)) {
|
||||
return;
|
||||
}
|
||||
|
||||
base::Value::Dict message;
|
||||
message.Set("type", "updateInk2Thumbnail");
|
||||
message.Set("pageNumber", page_index + 1);
|
||||
message.Set("imageData", std::move(image_data));
|
||||
message.Set("width", size.width());
|
||||
message.Set("height", size.height());
|
||||
client_->PostMessage(std::move(message));
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_PDF_INK2)
|
||||
|
||||
gfx::Point PdfViewWebPlugin::FrameToPdfCoordinates(
|
||||
|
@ -688,8 +688,6 @@ class PdfViewWebPlugin final : public PDFiumEngineClient,
|
||||
PdfViewWebPlugin& plugin);
|
||||
static std::unique_ptr<PdfInkModule> MaybeCreatePdfInkModule(
|
||||
PdfInkModuleClient* client);
|
||||
|
||||
void GenerateAndSendInkThumbnail(int page_index, const gfx::Size& size);
|
||||
#endif
|
||||
|
||||
// Converts `frame_coordinates` to PDF coordinates.
|
||||
|
@ -2766,6 +2766,13 @@ TEST_F(PdfViewWebPluginInkTest, UpdateCursor) {
|
||||
EXPECT_EQ(ui::mojom::CursorType::kPointer, cursor.type());
|
||||
}
|
||||
|
||||
TEST_F(PdfViewWebPluginInkTest, GetThumbnailSize) {
|
||||
SetUpWithTrivialInkStrokes();
|
||||
EXPECT_EQ(gfx::Size(50, 25),
|
||||
plugin_->ink_module_client_for_testing()->GetThumbnailSize(
|
||||
/*page_index=*/0));
|
||||
}
|
||||
|
||||
TEST_F(PdfViewWebPluginInkTest, GetZoom) {
|
||||
// Demonstrate that default zoom is identity.
|
||||
EXPECT_EQ(1.0f, plugin_->ink_module_client_for_testing()->GetZoom());
|
||||
@ -2796,36 +2803,6 @@ TEST_F(PdfViewWebPluginInkTest, GetZoom) {
|
||||
EXPECT_EQ(2.5f, plugin_->ink_module_client_for_testing()->GetZoom());
|
||||
}
|
||||
|
||||
TEST_F(PdfViewWebPluginInkTest, UpdateThumbnail) {
|
||||
SetUpWithTrivialInkStrokes();
|
||||
|
||||
EXPECT_CALL(*client_ptr_, PostMessage)
|
||||
.WillOnce([](const base::Value::Dict& dict) {
|
||||
auto expected = base::test::ParseJsonDict(R"({
|
||||
"type": "updateInk2Thumbnail",
|
||||
"pageNumber": 1,
|
||||
"width": 50,
|
||||
"height": 25,
|
||||
})");
|
||||
EXPECT_THAT(dict, base::test::DictionaryHasValues(expected));
|
||||
|
||||
// Test `dict` contains the image data, but not the exact value.
|
||||
const auto* blob = dict.FindBlob("imageData");
|
||||
ASSERT_TRUE(blob);
|
||||
EXPECT_FALSE(blob->empty());
|
||||
});
|
||||
|
||||
plugin_->ink_module_client_for_testing()->UpdateThumbnail(/*page_index=*/0);
|
||||
}
|
||||
|
||||
TEST_F(PdfViewWebPluginInkTest, UpdateThumbnailWithNoStrokes) {
|
||||
ON_CALL(*engine_ptr_, GetThumbnailSize)
|
||||
.WillByDefault(Return(gfx::Size(50, 25)));
|
||||
|
||||
EXPECT_CALL(*client_ptr_, PostMessage).Times(0);
|
||||
plugin_->ink_module_client_for_testing()->UpdateThumbnail(/*page_index=*/0);
|
||||
}
|
||||
|
||||
TEST_F(PdfViewWebPluginInkTest, AddUpdateDiscardStroke) {
|
||||
const PdfInkBrush kBrush(PdfInkBrush::Type::kPen, SK_ColorRED, /*size=*/4.0f);
|
||||
constexpr InkStrokeId kStrokeId(1);
|
||||
|
Reference in New Issue
Block a user