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