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