Add support for EMF rendering in embedder tests. This lets tests call FPDF_RenderPage(). Use it in an FPDFViewEmbedderTest to show FPDF_REVERSE_BYTE_ORDER does not work properly. BUG=pdfium:1281 Change-Id: I7539932ba0fce6273bcc238ecb0a4ff447128bb1 Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/53251 Reviewed-by: Tom Sepez <tsepez@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdf_view_embeddertest.cpp b/fpdfsdk/fpdf_view_embeddertest.cpp index 3a314ba..efa3c7b 100644 --- a/fpdfsdk/fpdf_view_embeddertest.cpp +++ b/fpdfsdk/fpdf_view_embeddertest.cpp
@@ -6,7 +6,9 @@ #include <limits> #include <memory> #include <string> +#include <vector> +#include "build/build_config.h" #include "core/fpdfapi/parser/cpdf_document.h" #include "fpdfsdk/cpdfsdk_helpers.h" #include "fpdfsdk/fpdf_view_c_api_test.h" @@ -904,3 +906,21 @@ EXPECT_TRUE(FPDF_DocumentHasValidCrossReferenceTable(doc.get())); } } + +#if defined(OS_WIN) +// Tests using FPDF_REVERSE_BYTE_ORDER with FPDF_RenderPage(). The two rendered +// EMFs should be different. +TEST_F(FPDFViewEmbedderTest, BUG_1281) { + ASSERT_TRUE(OpenDocument("rectangles.pdf")); + FPDF_PAGE page = LoadPage(0); + ASSERT_TRUE(page); + + std::vector<uint8_t> emf_normal = RenderPageWithFlagsToEmf(page, 0); + std::vector<uint8_t> emf_reverse_byte_order = + RenderPageWithFlagsToEmf(page, FPDF_REVERSE_BYTE_ORDER); + // TODO(https://crbug.com/pdfium/1281): These should not be equal. + EXPECT_EQ(emf_normal, emf_reverse_byte_order); + + UnloadPage(page); +} +#endif
diff --git a/testing/embedder_test.cpp b/testing/embedder_test.cpp index 13a3306..9e64ee5 100644 --- a/testing/embedder_test.cpp +++ b/testing/embedder_test.cpp
@@ -11,6 +11,7 @@ #include <memory> #include <string> #include <utility> +#include <vector> #include "core/fdrm/fx_crypt.h" #include "public/cpp/fpdf_scopers.h" @@ -378,6 +379,34 @@ return RenderPageWithFlags(page, nullptr, 0); } +#if defined(OS_WIN) +// static +std::vector<uint8_t> EmbedderTest::RenderPageWithFlagsToEmf(FPDF_PAGE page, + int flags) { + HDC dc = CreateEnhMetaFileA(nullptr, nullptr, nullptr, nullptr); + + int width = static_cast<int>(FPDF_GetPageWidth(page)); + int height = static_cast<int>(FPDF_GetPageHeight(page)); + HRGN rgn = CreateRectRgn(0, 0, width, height); + SelectClipRgn(dc, rgn); + DeleteObject(rgn); + + SelectObject(dc, GetStockObject(NULL_PEN)); + SelectObject(dc, GetStockObject(WHITE_BRUSH)); + // If a PS_NULL pen is used, the dimensions of the rectangle are 1 pixel less. + Rectangle(dc, 0, 0, width + 1, height + 1); + + FPDF_RenderPage(dc, page, 0, 0, width, height, 0, flags); + + HENHMETAFILE emf = CloseEnhMetaFile(dc); + size_t size_in_bytes = GetEnhMetaFileBits(emf, 0, nullptr); + std::vector<uint8_t> buffer(size_in_bytes); + GetEnhMetaFileBits(emf, size_in_bytes, buffer.data()); + DeleteEnhMetaFile(emf); + return buffer; +} +#endif // defined(OS_WIN) + FPDF_DOCUMENT EmbedderTest::OpenSavedDocument() { return OpenSavedDocumentWithPassword(nullptr); }
diff --git a/testing/embedder_test.h b/testing/embedder_test.h index 8f094c2..56bf61e 100644 --- a/testing/embedder_test.h +++ b/testing/embedder_test.h
@@ -9,7 +9,9 @@ #include <map> #include <memory> #include <string> +#include <vector> +#include "build/build_config.h" #include "public/cpp/fpdf_scopers.h" #include "public/fpdf_dataavail.h" #include "public/fpdf_ext.h" @@ -160,6 +162,12 @@ // Simplified form of RenderPageWithFlags() with no handle and no flags. static ScopedFPDFBitmap RenderPage(FPDF_PAGE page); +#if defined(OS_WIN) + // Convert |page| into EMF with the specified page rendering |flags|. + static std::vector<uint8_t> RenderPageWithFlagsToEmf(FPDF_PAGE page, + int flags); +#endif + protected: using PageNumberToHandleMap = std::map<int, FPDF_PAGE>;