0

Refactor drawing highlights and scrolling into functions for PDFs.

This refactors code to draw the PDF selection box highlights and
scrolling to bounding rects into functions that can be shared. This is a
precursor CL to rendering and scrolling to text fragment highlights.

Change-Id: I9e5c0d05a270d7ec930efba505cc9a88b4ab3a75
Bug: 383575917
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6219663
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Juan Mojica <juanmojica@google.com>
Cr-Commit-Position: refs/heads/main@{#1413793}
This commit is contained in:
Juan Mojica
2025-01-30 15:08:58 -08:00
committed by Chromium LUCI CQ
parent d49a776742
commit 55288fec1d
2 changed files with 63 additions and 35 deletions

@ -2173,27 +2173,7 @@ bool PDFiumEngine::SelectFindResult(bool forward) {
selection_.push_back(find_results_[current_find_index_.value()]);
// If the result is not in view, scroll to it.
gfx::Rect visible_rect = GetVisibleRect();
// Use zoom of 1.0 since `visible_rect` is without zoom.
const std::vector<gfx::Rect>& rects =
find_results_[current_find_index_.value()].GetScreenRects(
gfx::Point(), 1.0, layout_.options().default_page_orientation());
const gfx::Rect bounding_rect = gfx::UnionRects(rects);
if (!visible_rect.Contains(bounding_rect)) {
gfx::Point center = bounding_rect.CenterPoint();
// Make the page centered.
int new_y = CalculateCenterForZoom(center.y(), visible_rect.height(),
current_zoom_);
client_->ScrollToY(new_y);
// Only move horizontally if it's not visible.
if (center.x() < visible_rect.x() || center.x() > visible_rect.right()) {
int new_x = CalculateCenterForZoom(center.x(), visible_rect.width(),
current_zoom_);
client_->ScrollToX(new_x);
}
}
ScrollToBoundingRects(find_results_[current_find_index_.value()]);
client_->NotifySelectedFindResultChanged(
current_find_index_.value(), /*final_result=*/!search_in_progress_);
@ -3384,22 +3364,12 @@ void PDFiumEngine::DrawSelections(size_t progressive_index,
std::vector<gfx::Rect> highlighted_rects;
gfx::Rect visible_rect = GetVisibleRect();
for (const auto& range : selection_) {
if (range.page_index() != page_index)
if (range.page_index() != page_index) {
continue;
const std::vector<gfx::Rect>& rects =
range.GetScreenRects(visible_rect.origin(), current_zoom_,
layout_.options().default_page_orientation());
for (const auto& rect : rects) {
gfx::Rect visible_selection = gfx::IntersectRects(rect, dirty_in_screen);
if (visible_selection.IsEmpty()) {
continue;
}
visible_selection.Offset(-dirty_in_screen.OffsetFromOrigin());
Highlight(region.value(), visible_selection, kHighlightColor,
highlighted_rects);
}
DrawHighlightOnPage(range, dirty_in_screen, visible_rect, region.value(),
kHighlightColor, highlighted_rects);
}
for (const auto& highlight : form_highlights_) {
@ -3751,6 +3721,27 @@ void PDFiumEngine::DrawPageShadow(const gfx::Rect& page_rc,
DrawShadow(image_data, shadow_rect, page_rect, clip_rect, *page_shadow_);
}
void PDFiumEngine::DrawHighlightOnPage(
const PDFiumRange& range,
const gfx::Rect& dirty_in_screen,
const gfx::Rect& visible_rect,
const RegionData& region,
SkColor color,
std::vector<gfx::Rect>& highlighted_rects) const {
const std::vector<gfx::Rect>& rects =
range.GetScreenRects(visible_rect.origin(), current_zoom_,
layout_.options().default_page_orientation());
for (const auto& rect : rects) {
gfx::Rect visible_selection = gfx::IntersectRects(rect, dirty_in_screen);
if (visible_selection.IsEmpty()) {
continue;
}
visible_selection.Offset(-dirty_in_screen.OffsetFromOrigin());
Highlight(region, visible_selection, color, highlighted_rects);
}
}
std::optional<PDFiumEngine::RegionData> PDFiumEngine::GetRegion(
const gfx::Point& location,
SkBitmap& image_data) const {
@ -4020,6 +4011,31 @@ void PDFiumEngine::ScrollAnnotationIntoView(FPDF_ANNOTATION annot,
}
}
void PDFiumEngine::ScrollToBoundingRects(const PDFiumRange& range) {
// Use zoom of 1.0 since `visible_rect` is without zoom.
const std::vector<gfx::Rect>& rects = range.GetScreenRects(
gfx::Point(), 1.0, layout_.options().default_page_orientation());
const gfx::Rect bounding_rect = gfx::UnionRects(rects);
gfx::Rect visible_rect = GetVisibleRect();
// If `range` is in view, return early.
if (visible_rect.Contains(bounding_rect)) {
return;
}
gfx::Point center = bounding_rect.CenterPoint();
// Make the page centered.
int new_y =
CalculateCenterForZoom(center.y(), visible_rect.height(), current_zoom_);
client_->ScrollToY(new_y);
// Only move horizontally if it's not visible.
if (center.x() < visible_rect.x() || center.x() > visible_rect.right()) {
int new_x =
CalculateCenterForZoom(center.x(), visible_rect.width(), current_zoom_);
client_->ScrollToX(new_x);
}
}
void PDFiumEngine::OnFocusedAnnotationUpdated(FPDF_ANNOTATION annot,
int page_index) {
SetLinkUnderCursorForAnnotation(annot, page_index);

@ -834,6 +834,14 @@ class PDFiumEngine : public DocumentLoader::Client, public IFSDK_PAUSE {
const gfx::Rect& clip_rect,
SkBitmap& image_data);
// Draws the highlight for the provided `range` if visible.
void DrawHighlightOnPage(const PDFiumRange& range,
const gfx::Rect& dirty_in_screen,
const gfx::Rect& visible_rect,
const RegionData& region,
SkColor color,
std::vector<gfx::Rect>& highlighted_rects) const;
std::optional<RegionData> GetRegion(const gfx::Point& location,
SkBitmap& image_data) const;
@ -906,6 +914,10 @@ class PDFiumEngine : public DocumentLoader::Client, public IFSDK_PAUSE {
// Given `annot`, scroll the `annot` into view if not already in view.
void ScrollAnnotationIntoView(FPDF_ANNOTATION annot, int page_index);
// Scrolls to the bounding rectangles that represent the `range` on the
// screen.
void ScrollToBoundingRects(const PDFiumRange& range);
void OnFocusedAnnotationUpdated(FPDF_ANNOTATION annot, int page_index);
// Read the attachments' information inside the PDF document, and set