Avoid a case of float-int-float conversion in CPDF_Page
Currently, 2 CPDF_Page::GetDisplayMatrixForRect() callers do the
following:
1) Gets the page size as floats.
2) Constructs an int rectangle and passes that to
GetDisplayMatrixForRect().
3) GetDisplayMatrixForRect() converts the int values back to float.
Add a GetDisplayMatrixForRect() variant that takes a float rectangle to
avoid the int conversion. For now, keep the new method private, and only
expose a GetDisplayMatrix() method, which is what those 2 callers
really want.
Bug: 413582795
Change-Id: Ifb616092bd4f498969388892102d1236019fe8c3
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/132213
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_page.cpp b/core/fpdfapi/page/cpdf_page.cpp
index f62cd4f..0d56bfc 100644
--- a/core/fpdfapi/page/cpdf_page.cpp
+++ b/core/fpdfapi/page/cpdf_page.cpp
@@ -124,6 +124,11 @@
CFX_Matrix CPDF_Page::GetDisplayMatrixForRect(const FX_RECT& rect,
int rotation) const {
+ return GetDisplayMatrixForFloatRect(CFX_FloatRect(rect), rotation);
+}
+
+CFX_Matrix CPDF_Page::GetDisplayMatrixForFloatRect(const CFX_FloatRect& rect,
+ int rotation) const {
if (page_size_.width == 0 || page_size_.height == 0) {
return CFX_Matrix();
}
@@ -137,41 +142,40 @@
// This code implicitly inverts the y-axis to account for page coordinates
// pointing up and bitmap coordinates pointing down. (x0, y0) is the base
// point, (x1, y1) is that point translated on y and (x2, y2) is the point
- // translated on x. On rotation = 0, y0 is rect.bottom and the translation
- // to get y1 is performed as negative. This results in the desired
- // transformation.
+ // translated on x. On rotation = 0, y0 is rect.top and the translation to get
+ // y1 is performed as negative. This results in the desired transformation.
switch (rotation % 4) {
case 0:
x0 = rect.left;
- y0 = rect.bottom;
+ y0 = rect.top;
x1 = rect.left;
- y1 = rect.top;
+ y1 = rect.bottom;
x2 = rect.right;
- y2 = rect.bottom;
+ y2 = rect.top;
break;
case 1:
x0 = rect.left;
- y0 = rect.top;
+ y0 = rect.bottom;
+ x1 = rect.right;
+ y1 = rect.bottom;
+ x2 = rect.left;
+ y2 = rect.top;
+ break;
+ case 2:
+ x0 = rect.right;
+ y0 = rect.bottom;
x1 = rect.right;
y1 = rect.top;
x2 = rect.left;
y2 = rect.bottom;
break;
- case 2:
- x0 = rect.right;
- y0 = rect.top;
- x1 = rect.right;
- y1 = rect.bottom;
- x2 = rect.left;
- y2 = rect.top;
- break;
case 3:
x0 = rect.right;
- y0 = rect.bottom;
+ y0 = rect.top;
x1 = rect.left;
- y1 = rect.bottom;
+ y1 = rect.top;
x2 = rect.right;
- y2 = rect.top;
+ y2 = rect.bottom;
break;
default:
CHECK_LT(rotation, 0);
@@ -185,6 +189,11 @@
return page_matrix_ * matrix;
}
+CFX_Matrix CPDF_Page::GetDisplayMatrix() const {
+ const CFX_FloatRect rect(0, 0, GetPageWidth(), GetPageHeight());
+ return GetDisplayMatrixForFloatRect(rect, 0);
+}
+
int CPDF_Page::GetPageRotation() const {
RetainPtr<const CPDF_Object> pRotate =
GetPageAttr(pdfium::page_object::kRotate);
diff --git a/core/fpdfapi/page/cpdf_page.h b/core/fpdfapi/page/cpdf_page.h
index 8b87b84..3421ad9 100644
--- a/core/fpdfapi/page/cpdf_page.h
+++ b/core/fpdfapi/page/cpdf_page.h
@@ -74,6 +74,7 @@
void ParseContent();
const CFX_SizeF& GetPageSize() const { return page_size_; }
const CFX_Matrix& GetPageMatrix() const { return page_matrix_; }
+ CFX_Matrix GetDisplayMatrix() const;
int GetPageRotation() const;
RetainPtr<CPDF_Array> GetOrCreateAnnotsArray();
@@ -101,6 +102,8 @@
RetainPtr<CPDF_Object> GetMutablePageAttr(ByteStringView name);
RetainPtr<const CPDF_Object> GetPageAttr(ByteStringView name) const;
CFX_FloatRect GetBox(ByteStringView name) const;
+ CFX_Matrix GetDisplayMatrixForFloatRect(const CFX_FloatRect& rect,
+ int rotation) const;
CFX_SizeF page_size_;
CFX_Matrix page_matrix_;
diff --git a/core/fpdftext/cpdf_textpage.cpp b/core/fpdftext/cpdf_textpage.cpp
index c1fde9d..9fb7d24 100644
--- a/core/fpdftext/cpdf_textpage.cpp
+++ b/core/fpdftext/cpdf_textpage.cpp
@@ -272,12 +272,6 @@
return right <= left;
}
-CFX_Matrix GetPageMatrix(const CPDF_Page* pPage) {
- const FX_RECT rect(0, 0, static_cast<int>(pPage->GetPageWidth()),
- static_cast<int>(pPage->GetPageHeight()));
- return pPage->GetDisplayMatrixForRect(rect, 0);
-}
-
float GetFontSize(const CPDF_TextObject* text_object) {
bool has_font = text_object && text_object->GetFont();
return has_font ? text_object->GetFontSize() : kDefaultFontSize;
@@ -369,7 +363,7 @@
CPDF_TextPage::CharInfo::~CharInfo() = default;
CPDF_TextPage::CPDF_TextPage(const CPDF_Page* pPage, bool rtl)
- : page_(pPage), rtl_(rtl), display_matrix_(GetPageMatrix(pPage)) {
+ : page_(pPage), rtl_(rtl), display_matrix_(page_->GetDisplayMatrix()) {
Init();
}
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index 34abfae..efd9467 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -820,8 +820,7 @@
}
FX_RECT clip_rect = clipping_rect.ToFxRect();
- const FX_RECT rect(0, 0, pPage->GetPageWidth(), pPage->GetPageHeight());
- CFX_Matrix transform_matrix = pPage->GetDisplayMatrixForRect(rect, 0);
+ CFX_Matrix transform_matrix = pPage->GetDisplayMatrix();
if (matrix) {
transform_matrix *= CFXMatrixFromFSMatrix(*matrix);
}