0

[PDF Ink Signatures] Implement PdfViewWebPlugin::VisiblePageIndexFromPoint()

Implement this method by checking PDFiumEngine page contents rects to
find the one that contains the given point.

Bug: 335524380
Change-Id: Ic569cfbc13c5bd3f222c4873fb756fc68576ede0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5542804
Reviewed-by: Alan Screen <awscreen@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/main@{#1302331}
This commit is contained in:
Lei Zhang
2024-05-17 00:13:48 +00:00
committed by Chromium LUCI CQ
parent f227d98be1
commit 70c11b4df3
6 changed files with 83 additions and 7 deletions

@ -381,6 +381,8 @@ class PDFEngine {
const std::string& destination) = 0;
// Gets the index of the most visible page, or -1 if none are visible.
virtual int GetMostVisiblePage() = 0;
// Returns whether the page at `index` is visible or not.
virtual bool IsPageVisible(int index) const = 0;
// Gets the rectangle of the page not including the shadow.
virtual gfx::Rect GetPageBoundsRect(int index) = 0;
// Gets the rectangle of the page excluding any additional areas.

@ -1971,7 +1971,17 @@ SkBitmap PdfViewWebPlugin::GetImageForOcr(int32_t page_index,
}
int PdfViewWebPlugin::VisiblePageIndexFromPoint(const gfx::PointF& point) {
// TODO(crbug.com/335524380): Implement.
gfx::Point rounded_point = gfx::ToRoundedPoint(point);
for (int i = 0; i < engine_->GetNumberOfPages(); ++i) {
if (!engine_->IsPageVisible(i)) {
continue;
}
auto rect = engine_->GetPageContentsRect(i);
if (!rect.Contains(rounded_point)) {
continue;
}
return i;
}
return -1;
}

@ -2440,4 +2440,65 @@ TEST_F(PdfViewWebPluginPrintPreviewTest,
})"));
}
#if BUILDFLAG(ENABLE_PDF_INK2)
using PdfViewWebPluginInkTest = PdfViewWebPluginTest;
TEST_F(PdfViewWebPluginInkTest, VisiblePageIndexFromPoint) {
ON_CALL(*engine_ptr_, GetPageContentsRect)
.WillByDefault([](int page_index) -> gfx::Rect {
// Uniform 80x180 page sizes, with a `kVerticalEmptySpace` gap above
// every page.
constexpr int kVerticalEmptySpace = 20;
constexpr int kHeight = 180;
int y = kHeight * page_index + kVerticalEmptySpace * (page_index + 1);
return gfx::Rect(/*x=*/10, /*y=*/y, /*width=*/80, /*height=*/kHeight);
});
// Top-left corner of screen.
constexpr gfx::PointF kScreenTopLeftCorner(0.0f, 0.0f);
// Top-left corner of first page.
constexpr gfx::PointF kPage0TopLeftCorner(10.0f, 20.0f);
// Bottom-right corner of first page.
constexpr gfx::PointF kPage0BottomRightCorner(89.0f, 199.0f);
// Gap between first and second page.
constexpr gfx::PointF kPage0Page1Gap(50.0f, 201.0f);
// Top of second page.
constexpr gfx::PointF kPage1Top(50.0f, 220.0f);
// Middle of last page.
constexpr gfx::PointF kPage12Middle(50.0f, 2510.0f);
// Bottom of last page.
constexpr gfx::PointF kPage12Bottom(60.0f, 2599.0f);
// Beyond the last page.
constexpr gfx::PointF kPageBelowLast(60.0f, 2700.0f);
// Start with the first 2 pages visible.
ON_CALL(*engine_ptr_, IsPageVisible)
.WillByDefault([](int page_index) -> bool {
return page_index >= 0 && page_index <= 1;
});
EXPECT_EQ(-1, plugin_->VisiblePageIndexFromPoint(kScreenTopLeftCorner));
EXPECT_EQ(0, plugin_->VisiblePageIndexFromPoint(kPage0TopLeftCorner));
EXPECT_EQ(0, plugin_->VisiblePageIndexFromPoint(kPage0BottomRightCorner));
EXPECT_EQ(-1, plugin_->VisiblePageIndexFromPoint(kPage0Page1Gap));
EXPECT_EQ(1, plugin_->VisiblePageIndexFromPoint(kPage1Top));
EXPECT_EQ(-1, plugin_->VisiblePageIndexFromPoint(kPage12Middle));
EXPECT_EQ(-1, plugin_->VisiblePageIndexFromPoint(kPage12Bottom));
EXPECT_EQ(-1, plugin_->VisiblePageIndexFromPoint(kPageBelowLast));
// Change the visible page to the last page.
ON_CALL(*engine_ptr_, IsPageVisible)
.WillByDefault([](int page_index) -> bool { return page_index == 12; });
EXPECT_EQ(-1, plugin_->VisiblePageIndexFromPoint(kScreenTopLeftCorner));
EXPECT_EQ(-1, plugin_->VisiblePageIndexFromPoint(kPage0TopLeftCorner));
EXPECT_EQ(-1, plugin_->VisiblePageIndexFromPoint(kPage0BottomRightCorner));
EXPECT_EQ(-1, plugin_->VisiblePageIndexFromPoint(kPage0Page1Gap));
EXPECT_EQ(-1, plugin_->VisiblePageIndexFromPoint(kPage1Top));
EXPECT_EQ(12, plugin_->VisiblePageIndexFromPoint(kPage12Middle));
EXPECT_EQ(12, plugin_->VisiblePageIndexFromPoint(kPage12Bottom));
EXPECT_EQ(-1, plugin_->VisiblePageIndexFromPoint(kPageBelowLast));
}
#endif // BUILDFLAG(ENABLE_PDF_INK2)
} // namespace chrome_pdf

@ -3029,6 +3029,8 @@ void PDFiumEngine::CalculateVisiblePages() {
}
bool PDFiumEngine::IsPageVisible(int index) const {
// CalculateVisiblePages() must have been called first to populate
// `visible_pages_`. Otherwise, this will always return false.
return base::Contains(visible_pages_, index);
}

@ -144,6 +144,7 @@ class PDFiumEngine : public PDFEngine,
std::optional<PDFEngine::NamedDestination> GetNamedDestination(
const std::string& destination) override;
int GetMostVisiblePage() override;
bool IsPageVisible(int index) const override;
gfx::Rect GetPageBoundsRect(int index) override;
gfx::Rect GetPageContentsRect(int index) override;
gfx::Rect GetPageScreenRect(int page_index) const override;
@ -349,10 +350,6 @@ class PDFiumEngine : public PDFEngine,
// Calculates which pages should be displayed right now.
void CalculateVisiblePages();
// Returns true iff the given page index is visible. CalculateVisiblePages
// must have been called first.
bool IsPageVisible(int index) const;
// Internal interface that caches the page index requested by PDFium to get
// scrolled to. The cache is to be be used during the interval the PDF
// plugin has not finished handling the scroll request.

@ -82,11 +82,15 @@ class TestPDFiumEngine : public PDFiumEngine {
int GetNumberOfPages() const override;
// Returns an empty bookmark list.
base::Value::List GetBookmarks() override;
MOCK_METHOD(bool, IsPageVisible, (int), (const override));
MOCK_METHOD(gfx::Rect, GetPageContentsRect, (int), (override));
MOCK_METHOD(gfx::Rect, GetPageScreenRect, (int), (const override));
// Returns an empty bookmark list.
base::Value::List GetBookmarks() override;
MOCK_METHOD(void, SetGrayscale, (bool), (override));
uint32_t GetLoadedByteSize() override;