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_