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); }