From ce8e51e6c444f6caaa160bf8b1decd5d7ec84e6f Mon Sep 17 00:00:00 2001 From: rbpotter Date: Fri, 28 Apr 2017 12:42:47 -0700 Subject: Fix rotations Normalize rotations read from PDF documents. Make FPDFPage_GetRotation always return a value 0 to 3 as specified in fpdf_edit.h instead of returning the page rotation / 90 (page rotation may be negative for some PDFs). BUG=chromium:713197 Change-Id: Ie477803f7d298b777a3ace89b21cfda8b7f6808b Reviewed-on: https://pdfium-review.googlesource.com/4532 Reviewed-by: Lei Zhang Commit-Queue: Lei Zhang --- core/fpdfapi/page/cpdf_page.cpp | 11 +++++++---- core/fpdfapi/page/cpdf_page.h | 1 + fpdfsdk/fpdfedit_embeddertest.cpp | 10 ++++++++++ fpdfsdk/fpdfeditpage.cpp | 15 +-------------- fpdfsdk/fpdfview.cpp | 14 +------------- testing/resources/bug_713197.in | 27 +++++++++++++++++++++++++++ testing/resources/bug_713197.pdf | 34 ++++++++++++++++++++++++++++++++++ 7 files changed, 81 insertions(+), 31 deletions(-) create mode 100644 testing/resources/bug_713197.in create mode 100644 testing/resources/bug_713197.pdf diff --git a/core/fpdfapi/page/cpdf_page.cpp b/core/fpdfapi/page/cpdf_page.cpp index 496ed7cc58..5ea575e307 100644 --- a/core/fpdfapi/page/cpdf_page.cpp +++ b/core/fpdfapi/page/cpdf_page.cpp @@ -35,10 +35,7 @@ CPDF_Page::CPDF_Page(CPDF_Document* pDocument, CPDF_Object* pageAttr = GetPageAttr("Resources"); m_pResources = pageAttr ? pageAttr->GetDict() : nullptr; m_pPageResources = m_pResources; - CPDF_Object* pRotate = GetPageAttr("Rotate"); - int rotate = pRotate ? pRotate->GetInteger() / 90 % 4 : 0; - if (rotate < 0) - rotate += 4; + int rotate = GetPageRotation(); CPDF_Array* pMediaBox = ToArray(GetPageAttr("MediaBox")); CFX_FloatRect mediabox; @@ -176,6 +173,12 @@ CFX_Matrix CPDF_Page::GetDisplayMatrix(int xPos, return matrix; } +int CPDF_Page::GetPageRotation() const { + CPDF_Object* pRotate = GetPageAttr("Rotate"); + int rotate = pRotate ? (pRotate->GetInteger() / 90) % 4 : 0; + return (rotate < 0) ? (rotate + 4) : rotate; +} + bool GraphicsData::operator<(const GraphicsData& other) const { if (fillAlpha != other.fillAlpha) return fillAlpha < other.fillAlpha; diff --git a/core/fpdfapi/page/cpdf_page.h b/core/fpdfapi/page/cpdf_page.h index 076ab3f93b..b0dfa26124 100644 --- a/core/fpdfapi/page/cpdf_page.h +++ b/core/fpdfapi/page/cpdf_page.h @@ -56,6 +56,7 @@ class CPDF_Page : public CPDF_PageObjectHolder { float GetPageHeight() const { return m_PageHeight; } CFX_FloatRect GetPageBBox() const { return m_BBox; } const CFX_Matrix& GetPageMatrix() const { return m_PageMatrix; } + int GetPageRotation() const; CPDF_Object* GetPageAttr(const CFX_ByteString& name) const; CPDF_PageRenderCache* GetRenderCache() const { return m_pPageRender.get(); } diff --git a/fpdfsdk/fpdfedit_embeddertest.cpp b/fpdfsdk/fpdfedit_embeddertest.cpp index 952564db49..d62f5ca85c 100644 --- a/fpdfsdk/fpdfedit_embeddertest.cpp +++ b/fpdfsdk/fpdfedit_embeddertest.cpp @@ -694,3 +694,13 @@ TEST_F(FPDFEditEmbeddertest, LoadCIDType2Font) { ASSERT_TRUE(widths_array); CheckCompositeFontWidths(widths_array, typed_font); } + +TEST_F(FPDFEditEmbeddertest, NormalizeNegativeRotation) { + // Load document with a -90 degree rotation + EXPECT_TRUE(OpenDocument("bug_713197.pdf")); + FPDF_PAGE page = LoadPage(0); + EXPECT_NE(nullptr, page); + + EXPECT_EQ(3, FPDFPage_GetRotation(page)); + UnloadPage(page); +} diff --git a/fpdfsdk/fpdfeditpage.cpp b/fpdfsdk/fpdfeditpage.cpp index 511b7f5b4b..739723f6ee 100644 --- a/fpdfsdk/fpdfeditpage.cpp +++ b/fpdfsdk/fpdfeditpage.cpp @@ -133,20 +133,7 @@ DLLEXPORT int STDCALL FPDFPage_GetRotation(FPDF_PAGE page) { CPDF_Page* pPage = CPDFPageFromFPDFPage(page); if (!IsPageObject(pPage)) return -1; - - CPDF_Dictionary* pDict = pPage->m_pFormDict; - while (pDict) { - if (pDict->KeyExist("Rotate")) { - CPDF_Object* pRotateObj = pDict->GetObjectFor("Rotate")->GetDirect(); - return pRotateObj ? pRotateObj->GetInteger() / 90 : 0; - } - if (!pDict->KeyExist("Parent")) - break; - - pDict = ToDictionary(pDict->GetObjectFor("Parent")->GetDirect()); - } - - return 0; + return pPage->GetPageRotation(); } DLLEXPORT void STDCALL FPDFPage_InsertObject(FPDF_PAGE page, diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp index 4fea392228..c928ebe445 100644 --- a/fpdfsdk/fpdfview.cpp +++ b/fpdfsdk/fpdfview.cpp @@ -740,19 +740,7 @@ FX_RECT GetMaskDimensionsAndOffsets(CPDF_Page* pPage, static_cast(mask_box.bottom * scale_y); // Get page rotation - int page_rotation = 0; - CPDF_Dictionary* pDict = pPage->m_pFormDict; - while (pDict) { - if (pDict->KeyExist("Rotate")) { - CPDF_Object* pRotateObj = pDict->GetObjectFor("Rotate")->GetDirect(); - page_rotation = pRotateObj ? pRotateObj->GetInteger() / 90 : 0; - break; - } - if (!pDict->KeyExist("Parent")) - break; - - pDict = ToDictionary(pDict->GetObjectFor("Parent")->GetDirect()); - } + int page_rotation = pPage->GetPageRotation(); // Compute offsets int offset_x = 0; diff --git a/testing/resources/bug_713197.in b/testing/resources/bug_713197.in new file mode 100644 index 0000000000..49eaee2d93 --- /dev/null +++ b/testing/resources/bug_713197.in @@ -0,0 +1,27 @@ +{{header}} +{{object 1 0}} << + /Type /Catalog + /Pages 2 0 R +>> +endobj +{{object 2 0}}<< + /Type /Pages + /MediaBox [0 0 600 800] + /Count 1 + /Kids [ 3 0 R ] +>> +endobj +{{object 3 0}}<< + /Type /Page + /Parent 2 0 R + /Resources <<>> + /Rotate -90 +>> +endobj +{{xref}} +trailer << + /Size 4 + /Root 1 0 R +>> +{{startxref}} +%%EOF diff --git a/testing/resources/bug_713197.pdf b/testing/resources/bug_713197.pdf new file mode 100644 index 0000000000..571cde9d7f --- /dev/null +++ b/testing/resources/bug_713197.pdf @@ -0,0 +1,34 @@ +%PDF-1.7 +% ò¤ô +1 0 obj << + /Type /Catalog + /Pages 2 0 R +>> +endobj +2 0 obj<< + /Type /Pages + /MediaBox [0 0 600 800] + /Count 1 + /Kids [ 3 0 R ] +>> +endobj +3 0 obj<< + /Type /Page + /Parent 2 0 R + /Resources <<>> + /Rotate -90 +>> +endobj +xref +0 4 +0000000000 65535 f +0000000016 00000 n +0000000074 00000 n +0000000171 00000 n +trailer << + /Size 4 + /Root 1 0 R +>> +startxref +260 +%%EOF -- cgit v1.2.3