diff --git a/pdf/pdf_ink_module.cc b/pdf/pdf_ink_module.cc index ab0aa165bba4f..f6f4aaeba62e4 100644 --- a/pdf/pdf_ink_module.cc +++ b/pdf/pdf_ink_module.cc @@ -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); } } diff --git a/pdf/pdf_ink_module.h b/pdf/pdf_ink_module.h index dbec3ee9c8bd0..ab6e476e0eec6 100644 --- a/pdf/pdf_ink_module.h +++ b/pdf/pdf_ink_module.h @@ -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; diff --git a/pdf/pdf_ink_module_client.h b/pdf/pdf_ink_module_client.h index de72082ff9b27..3f82dd8a6cd26 100644 --- a/pdf/pdf_ink_module_client.h +++ b/pdf/pdf_ink_module_client.h @@ -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; diff --git a/pdf/pdf_ink_module_unittest.cc b/pdf/pdf_ink_module_unittest.cc index d65f607a5afd6..dbc31bb13b602 100644 --- a/pdf/pdf_ink_module_unittest.cc +++ b/pdf/pdf_ink_module_unittest.cc @@ -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) { diff --git a/pdf/pdf_view_web_plugin.cc b/pdf/pdf_view_web_plugin.cc index 57323cfad1cc8..e99c99a9190ec 100644 --- a/pdf/pdf_view_web_plugin.cc +++ b/pdf/pdf_view_web_plugin.cc @@ -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( diff --git a/pdf/pdf_view_web_plugin.h b/pdf/pdf_view_web_plugin.h index 886d8d06740a8..2f4912ede5c08 100644 --- a/pdf/pdf_view_web_plugin.h +++ b/pdf/pdf_view_web_plugin.h @@ -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. diff --git a/pdf/pdf_view_web_plugin_unittest.cc b/pdf/pdf_view_web_plugin_unittest.cc index 50939b98987ad..54ec7a38b413a 100644 --- a/pdf/pdf_view_web_plugin_unittest.cc +++ b/pdf/pdf_view_web_plugin_unittest.cc @@ -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);