Commit a7fe60e4 authored by Hui Yingst's avatar Hui Yingst Committed by Chromium LUCI CQ

Handle out-of-range coordinates from an XYZ named destination.

The in-page coordinates from an XYZ named destination sometimes can be
out of the range of the PDF's page width and height.

This CL preprocesses such out-of-range x and y coordinates before
converting them from in-page coordinates to in-screen coordinates.

Bug: 1157061
Change-Id: I3279890459188e3856c75478caebefa6bafaa655
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2633191
Commit-Queue: Hui Yingst <nigi@chromium.org>
Reviewed-by: default avatardsinclair <dsinclair@chromium.org>
Cr-Commit-Position: refs/heads/master@{#846253}
parent f8e6b326
...@@ -392,6 +392,10 @@ std::string GetXYZParamsString(FPDF_DEST dest, PDFiumPage* page) { ...@@ -392,6 +392,10 @@ std::string GetXYZParamsString(FPDF_DEST dest, PDFiumPage* page) {
return ""; return "";
} }
// Handle out-of-range page coordinates.
x = has_x_coord ? page->PreProcessInPageCoordX(x) : 0;
y = has_y_coord ? page->PreProcessInPageCoordY(y) : 0;
// Convert in-page coordinates to in-screen coordinates. // Convert in-page coordinates to in-screen coordinates.
gfx::PointF xy(x, y); gfx::PointF xy(x, y);
gfx::PointF screen_coords = page->TransformPageToScreenXY(xy); gfx::PointF screen_coords = page->TransformPageToScreenXY(xy);
......
...@@ -852,10 +852,15 @@ PDFiumPage::Area PDFiumPage::GetDestinationTarget(FPDF_DEST destination, ...@@ -852,10 +852,15 @@ PDFiumPage::Area PDFiumPage::GetDestinationTarget(FPDF_DEST destination,
base::Optional<float> x; base::Optional<float> x;
base::Optional<float> y; base::Optional<float> y;
GetPageDestinationTarget(destination, &x, &y, &target->zoom); GetPageDestinationTarget(destination, &x, &y, &target->zoom);
if (x)
target->x_in_pixels = TransformPageToScreenX(x.value()); if (x) {
if (y) target->x_in_pixels =
target->y_in_pixels = TransformPageToScreenY(y.value()); TransformPageToScreenX(PreProcessInPageCoordX(x.value()));
}
if (y) {
target->y_in_pixels =
TransformPageToScreenY(PreProcessInPageCoordY(y.value()));
}
return DOCLINK_AREA; return DOCLINK_AREA;
} }
...@@ -890,6 +895,18 @@ void PDFiumPage::GetPageDestinationTarget(FPDF_DEST destination, ...@@ -890,6 +895,18 @@ void PDFiumPage::GetPageDestinationTarget(FPDF_DEST destination,
*zoom_value = zoom; *zoom_value = zoom;
} }
float PDFiumPage::PreProcessInPageCoordX(float x) {
// If `x` < 0, scroll to the left side of the page.
// If `x` > width, scroll to the right side of the page.
return std::max<float>(std::min<float>(x, FPDF_GetPageWidthF(GetPage())), 0);
}
float PDFiumPage::PreProcessInPageCoordY(float y) {
// If `y` < 0, it is a valid input, no extra handling is needed.
// If `y` > height, scroll to the top of the page.
return std::min<float>(y, FPDF_GetPageHeightF(GetPage()));
}
gfx::PointF PDFiumPage::TransformPageToScreenXY(const gfx::PointF& xy) { gfx::PointF PDFiumPage::TransformPageToScreenXY(const gfx::PointF& xy) {
if (!available_) if (!available_)
return gfx::PointF(); return gfx::PointF();
......
...@@ -118,6 +118,11 @@ class PDFiumPage { ...@@ -118,6 +118,11 @@ class PDFiumPage {
base::Optional<float>* dest_y, base::Optional<float>* dest_y,
base::Optional<float>* zoom_value); base::Optional<float>* zoom_value);
// For a named destination with "XYZ" view fit type, pre-processes the in-page
// x/y coordinate in case it's out of the range of the page dimension.
float PreProcessInPageCoordX(float x);
float PreProcessInPageCoordY(float y);
// Transforms an (x, y) position in page coordinates to screen coordinates. // Transforms an (x, y) position in page coordinates to screen coordinates.
gfx::PointF TransformPageToScreenXY(const gfx::PointF& xy); gfx::PointF TransformPageToScreenXY(const gfx::PointF& xy);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment