Add TransFormWithClipAndSaveWithLocale embedder test.
Further exercise FPDFPage_TransFormWithClip() and make sure it works
correctly independent of the locale.
Copy over Chromium's base::ScopedLocale class for use in the new test.
BUG=chromium:970047
Change-Id: Ifa3cb2ad8c71902fc7fe893f0793d7e59ee574ab
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/56234
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index 42f2093..91a2ccb 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -284,6 +284,7 @@
"core/fxcrt",
"testing:embedder_test_support",
"testing:test_support",
+ "third_party:pdfium_base_test_support",
"//testing/gmock",
"//testing/gtest",
]
diff --git a/fpdfsdk/fpdf_transformpage_embeddertest.cpp b/fpdfsdk/fpdf_transformpage_embeddertest.cpp
index db8e516..ff2fbcf 100644
--- a/fpdfsdk/fpdf_transformpage_embeddertest.cpp
+++ b/fpdfsdk/fpdf_transformpage_embeddertest.cpp
@@ -3,8 +3,14 @@
// found in the LICENSE file.
#include "public/fpdf_transformpage.h"
+
+#include "build/build_config.h"
#include "testing/embedder_test.h"
+#if defined(OS_LINUX) || defined(OS_FUCHSIA)
+#include "third_party/base/test/scoped_locale.h"
+#endif
+
class FPDFTransformEmbedderTest : public EmbedderTest {};
TEST_F(FPDFTransformEmbedderTest, GetBoundingBoxes) {
@@ -450,3 +456,64 @@
CloseSavedDocument();
}
}
+
+#if defined(OS_LINUX) || defined(OS_FUCHSIA)
+TEST_F(FPDFTransformEmbedderTest, TransFormWithClipAndSaveWithLocale) {
+ const char kOriginalMD5[] = "0a90de37f52127619c3dfb642b5fa2fe";
+ const char kShrunkMD5[] = "f4136cc9209207ab60eb8381a3df2e69";
+
+ pdfium::base::ScopedLocale scoped_locale("da_DK.UTF-8");
+
+ {
+ ASSERT_TRUE(OpenDocument("rectangles.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ {
+ // Render the page as is.
+ const int page_width = static_cast<int>(FPDF_GetPageWidth(page));
+ const int page_height = static_cast<int>(FPDF_GetPageHeight(page));
+ EXPECT_EQ(200, page_width);
+ EXPECT_EQ(300, page_height);
+ ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
+ CompareBitmap(bitmap.get(), page_width, page_height, kOriginalMD5);
+ }
+
+ {
+ // Render the page after transforming.
+ // Note that the change should affect the rendering, but does not.
+ // It should behaves just like the case below, rather than the case above.
+ // TODO(bug_1328): The checksum below should be |kShrunkMD5|.
+ const FS_MATRIX half_matrix{0.5, 0, 0, 0.5, 0, 0};
+ EXPECT_TRUE(FPDFPage_TransFormWithClip(page, &half_matrix, nullptr));
+ const int page_width = static_cast<int>(FPDF_GetPageWidth(page));
+ const int page_height = static_cast<int>(FPDF_GetPageHeight(page));
+ EXPECT_EQ(200, page_width);
+ EXPECT_EQ(300, page_height);
+ ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
+ CompareBitmap(bitmap.get(), page_width, page_height, kOriginalMD5);
+ }
+
+ UnloadPage(page);
+ }
+
+ {
+ // Save a copy, open the copy, and render it.
+ // Note that it renders the transform.
+ EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
+ ASSERT_TRUE(OpenSavedDocument());
+ FPDF_PAGE saved_page = LoadSavedPage(0);
+ ASSERT_TRUE(saved_page);
+
+ const int page_width = static_cast<int>(FPDF_GetPageWidth(saved_page));
+ const int page_height = static_cast<int>(FPDF_GetPageHeight(saved_page));
+ EXPECT_EQ(200, page_width);
+ EXPECT_EQ(300, page_height);
+ ScopedFPDFBitmap bitmap = RenderSavedPage(saved_page);
+ CompareBitmap(bitmap.get(), page_width, page_height, kShrunkMD5);
+
+ CloseSavedPage(saved_page);
+ CloseSavedDocument();
+ }
+}
+#endif // defined(OS_LINUX) || defined(OS_FUCHSIA)
diff --git a/third_party/BUILD.gn b/third_party/BUILD.gn
index 275787c..dce2b1f 100644
--- a/third_party/BUILD.gn
+++ b/third_party/BUILD.gn
@@ -651,6 +651,25 @@
}
}
+jumbo_source_set("pdfium_base_test_support") {
+ testonly = true
+ configs -= [ "//build/config/compiler:chromium_code" ]
+ configs += [
+ "//build/config/compiler:no_chromium_code",
+ ":pdfium_third_party_config",
+ ]
+ sources = []
+ deps = []
+
+ if (is_posix || is_fuchsia) {
+ sources += [
+ "base/test/scoped_locale.cc",
+ "base/test/scoped_locale.h",
+ ]
+ deps += [ "//testing/gtest" ]
+ }
+}
+
jumbo_source_set("skia_shared") {
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [
diff --git a/third_party/base/test/scoped_locale.cc b/third_party/base/test/scoped_locale.cc
new file mode 100644
index 0000000..2643dd9
--- /dev/null
+++ b/third_party/base/test/scoped_locale.cc
@@ -0,0 +1,25 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/base/test/scoped_locale.h"
+
+#include <locale.h>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace pdfium {
+namespace base {
+
+ScopedLocale::ScopedLocale(const std::string& locale) {
+ prev_locale_ = setlocale(LC_ALL, nullptr);
+ EXPECT_TRUE(setlocale(LC_ALL, locale.c_str()) != nullptr)
+ << "Failed to set locale: " << locale;
+}
+
+ScopedLocale::~ScopedLocale() {
+ EXPECT_STREQ(prev_locale_.c_str(), setlocale(LC_ALL, prev_locale_.c_str()));
+}
+
+} // namespace base
+} // namespace pdfium
diff --git a/third_party/base/test/scoped_locale.h b/third_party/base/test/scoped_locale.h
new file mode 100644
index 0000000..ef6d6ea
--- /dev/null
+++ b/third_party/base/test/scoped_locale.h
@@ -0,0 +1,30 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BASE_TEST_SCOPED_LOCALE_H_
+#define THIRD_PARTY_BASE_TEST_SCOPED_LOCALE_H_
+
+#include <string>
+
+namespace pdfium {
+namespace base {
+
+// Sets the given |locale| on construction, and restores the previous locale
+// on destruction.
+class ScopedLocale {
+ public:
+ explicit ScopedLocale(const std::string& locale);
+ ~ScopedLocale();
+
+ private:
+ std::string prev_locale_;
+
+ ScopedLocale(const ScopedLocale&) = delete;
+ ScopedLocale& operator=(const ScopedLocale&) = delete;
+};
+
+} // namespace base
+} // namespace pdfium
+
+#endif // THIRD_PARTY_BASE_TEST_SCOPED_LOCALE_H_