Run pdfium_unittests on Linux with hermetic font configuration

* Verified with strace that system fonts are not loaded
* For now, hermetic fonts are only set up on Linux.
  * It's unclear if we want to do this on all platforms.
* Arial/Arimo are metric-compatible, so they are chosen in tests
  * The test font changed from Arial Black to Arial Bold, so some
    test expectations need to be updated for the new font width.

Previous CL:
https://pdfium-review.googlesource.com/c/pdfium/+/86175

Bug: chromium:1250250
Change-Id: I6b8400fd5e76f3b4ac4755ddd5ae8f84a7ca7cd2
R=thestig
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/86370
Auto-Submit: Thomas Anderson <thomasanderson@chromium.org>
Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/.gitignore b/.gitignore
index 2e2ba13..783e7ca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,6 +18,7 @@
 /third_party/markupsafe
 /third_party/nasm
 /third_party/skia
+/third_party/test_fonts
 /third_party/zlib
 /tools/clang
 /tools/code_coverage
diff --git a/DEPS b/DEPS
index 9393a0b..580f2cb 100644
--- a/DEPS
+++ b/DEPS
@@ -121,6 +121,10 @@
   # and whatever else without interference from each other.
   'skia_revision': '2f7c3f51e48e8c5384b4679e2024e9369addb44f',
   # Three lines of non-changing comments so that
+  # the commit queue can handle CLs rolling test_fonts
+  # and whatever else without interference from each other.
+  'test_fonts_revision': '7f51783942943e965cd56facf786544ccfc07713',
+  # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling tools_memory
   # and whatever else without interference from each other.
   'tools_memory_revision': '4dc64cab424aec02f60d892e857cc9a0155ea4fc',
@@ -256,6 +260,10 @@
   'third_party/skia':
     Var('chromium_git') + '/skia.git@' +  Var('skia_revision'),
 
+  'third_party/test_fonts':
+    Var('chromium_git') + '/chromium/src/third_party/test_fonts.git@' +
+        Var('test_fonts_revision'),
+
   'third_party/zlib':
     Var('chromium_git') + '/chromium/src/third_party/zlib.git@' +
         Var('zlib_revision'),
@@ -465,6 +473,18 @@
                '--arch=x64'],
   },
   {
+    'name': 'test_fonts',
+    'pattern': '.',
+    'action': [ 'python3',
+                'third_party/depot_tools/download_from_google_storage.py',
+                '--no_resume',
+                '--extract',
+                '--no_auth',
+                '--bucket', 'chromium-fonts',
+                '-s', 'third_party/test_fonts/test_fonts.tar.gz.sha1',
+    ],
+  },
+  {
     'name': 'msan_chained_origins',
     'pattern': '.',
     'condition': 'checkout_instrumented_libraries',
diff --git a/testing/BUILD.gn b/testing/BUILD.gn
index 3f42188..5b7215f 100644
--- a/testing/BUILD.gn
+++ b/testing/BUILD.gn
@@ -48,6 +48,9 @@
     ]
     configs += [ "//v8:external_startup_data" ]
   }
+  if (is_linux || is_chromeos) {
+    public_deps += [ "//third_party/test_fonts" ]
+  }
 }
 
 source_set("path_service") {
diff --git a/testing/pdf_test_environment.cpp b/testing/pdf_test_environment.cpp
index 2ab98f4..1148d5a 100644
--- a/testing/pdf_test_environment.cpp
+++ b/testing/pdf_test_environment.cpp
@@ -5,6 +5,7 @@
 #include "testing/pdf_test_environment.h"
 
 #include "core/fxge/cfx_gemodule.h"
+#include "testing/utils/path_service.h"
 
 PDFTestEnvironment::PDFTestEnvironment() = default;
 
@@ -12,6 +13,15 @@
 
 // testing::Environment:
 void PDFTestEnvironment::SetUp() {
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+  if (PathService::GetExecutableDir(&font_path_)) {
+    font_path_ += "/test_fonts";
+    font_paths_[0] = font_path_.c_str();
+    font_paths_[1] = nullptr;
+    CFX_GEModule::Create(font_paths_);
+    return;
+  }
+#endif
   CFX_GEModule::Create(nullptr);
 }
 
diff --git a/testing/pdf_test_environment.h b/testing/pdf_test_environment.h
index 3bb7ad0..d8fda31 100644
--- a/testing/pdf_test_environment.h
+++ b/testing/pdf_test_environment.h
@@ -5,6 +5,9 @@
 #ifndef TESTING_PDF_TEST_ENVIRONMENT_H_
 #define TESTING_PDF_TEST_ENVIRONMENT_H_
 
+#include <string>
+
+#include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 class PDFTestEnvironment : public testing::Environment {
@@ -15,6 +18,12 @@
   // testing::Environment:
   void SetUp() override;
   void TearDown() override;
+
+ private:
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+  std::string font_path_;
+  const char* font_paths_[2];
+#endif
 };
 
 #endif  // TESTING_PDF_TEST_ENVIRONMENT_H_
diff --git a/xfa/fde/cfde_texteditengine_unittest.cpp b/xfa/fde/cfde_texteditengine_unittest.cpp
index b532770..6c5cdec 100644
--- a/xfa/fde/cfde_texteditengine_unittest.cpp
+++ b/xfa/fde/cfde_texteditengine_unittest.cpp
@@ -4,6 +4,7 @@
 
 #include "xfa/fde/cfde_texteditengine.h"
 
+#include "build/build_config.h"
 #include "core/fxcrt/fx_codepage.h"
 #include "core/fxcrt/fx_extension.h"
 #include "core/fxge/text_char_pos.h"
@@ -39,7 +40,12 @@
   ~CFDE_TextEditEngineTest() override = default;
 
   void SetUp() override {
-    font_ = CFGAS_GEFont::LoadFont(L"Arial Black", 0, FX_CodePage::kDefANSI);
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+    const wchar_t kFontFamily[] = L"Arimo Bold";
+#else
+    const wchar_t kFontFamily[] = L"Arial Bold";
+#endif
+    font_ = CFGAS_GEFont::LoadFont(kFontFamily, 0, FX_CodePage::kDefANSI);
     ASSERT_TRUE(font_);
 
     engine_ = std::make_unique<CFDE_TextEditEngine>();
@@ -140,7 +146,7 @@
 
   // Insert with limited area and over-fill
   engine()->LimitHorizontalScroll(true);
-  engine()->SetAvailableWidth(60.0f);  // Fits 'Hello Wo'.
+  engine()->SetAvailableWidth(52.0f);  // Fits 'Hello Wo'.
   engine()->Insert(0, L"Hello");
   EXPECT_FALSE(delegate->text_is_full);
   engine()->Insert(5, L" World");
@@ -267,8 +273,8 @@
   EXPECT_EQ(0U, engine()->GetWidthOfChar(0));
 
   engine()->Insert(0, L"Hello World");
-  EXPECT_EQ(199920U, engine()->GetWidthOfChar(0));
-  EXPECT_EQ(159840U, engine()->GetWidthOfChar(1));
+  EXPECT_EQ(173280U, engine()->GetWidthOfChar(0));
+  EXPECT_EQ(133440U, engine()->GetWidthOfChar(1));
 
   engine()->Insert(0, L"\t");
   EXPECT_EQ(0U, engine()->GetWidthOfChar(0));
@@ -469,7 +475,7 @@
   EXPECT_EQ(11U, engine()->GetIndexForPoint({999999.0f, 9999999.0f}));
   EXPECT_EQ(11U, engine()->GetIndexForPoint({999999.0f, 0.0f}));
   EXPECT_EQ(1U, engine()->GetIndexForPoint({5.0f, 5.0f}));
-  EXPECT_EQ(1U, engine()->GetIndexForPoint({10.0f, 5.0f}));
+  EXPECT_EQ(2U, engine()->GetIndexForPoint({10.0f, 5.0f}));
 }
 
 TEST_F(CFDE_TextEditEngineTest, GetIndexForPointLineWrap) {
@@ -479,8 +485,8 @@
                    L"getting indexes on multi-line edits.");
   EXPECT_EQ(0U, engine()->GetIndexForPoint({0.0f, 0.0f}));
   EXPECT_EQ(87U, engine()->GetIndexForPoint({999999.0f, 9999999.0f}));
-  EXPECT_EQ(11U, engine()->GetIndexForPoint({999999.0f, 0.0f}));
-  EXPECT_EQ(12U, engine()->GetIndexForPoint({1.0f, 10.0f}));
+  EXPECT_EQ(18U, engine()->GetIndexForPoint({999999.0f, 0.0f}));
+  EXPECT_EQ(19U, engine()->GetIndexForPoint({1.0f, 10.0f}));
   EXPECT_EQ(1U, engine()->GetIndexForPoint({5.0f, 5.0f}));
   EXPECT_EQ(2U, engine()->GetIndexForPoint({10.0f, 5.0f}));
 }
@@ -532,19 +538,19 @@
   EXPECT_EQ(0, char_info.first);
   EXPECT_FLOAT_EQ(0.0f, char_info.second.Left());
   EXPECT_FLOAT_EQ(0.0f, char_info.second.Top());
-  EXPECT_FLOAT_EQ(9.996f, char_info.second.Width());
+  EXPECT_FLOAT_EQ(8.664f, char_info.second.Width());
   EXPECT_FLOAT_EQ(12.0f, char_info.second.Height());
 
   char_info = engine()->GetCharacterInfo(1);
   EXPECT_EQ(0, char_info.first);
-  EXPECT_FLOAT_EQ(9.996f, char_info.second.Left());
+  EXPECT_FLOAT_EQ(8.664f, char_info.second.Left());
   EXPECT_FLOAT_EQ(0.0f, char_info.second.Top());
-  EXPECT_FLOAT_EQ(3.996f, char_info.second.Width());
+  EXPECT_FLOAT_EQ(3.324f, char_info.second.Width());
   EXPECT_FLOAT_EQ(12.0f, char_info.second.Height());
 
   char_info = engine()->GetCharacterInfo(2);
   EXPECT_EQ(0, char_info.first);
-  EXPECT_FLOAT_EQ(13.992f, char_info.second.Left());
+  EXPECT_FLOAT_EQ(11.988f, char_info.second.Left());
   EXPECT_FLOAT_EQ(0.0f, char_info.second.Top());
   EXPECT_FLOAT_EQ(3.996f, char_info.second.Width());
   EXPECT_FLOAT_EQ(12.0f, char_info.second.Height());
@@ -554,7 +560,7 @@
   // the end.
   char_info = engine()->GetCharacterInfo(3);
   EXPECT_EQ(0, char_info.first);
-  EXPECT_FLOAT_EQ(17.988f, char_info.second.Left());
+  EXPECT_FLOAT_EQ(15.984, char_info.second.Left());
   EXPECT_FLOAT_EQ(0.0f, char_info.second.Top());
   EXPECT_FLOAT_EQ(0.0f, char_info.second.Width());
   EXPECT_FLOAT_EQ(12.0f, char_info.second.Height());
diff --git a/xfa/fgas/layout/cfgas_rtfbreak_unittest.cpp b/xfa/fgas/layout/cfgas_rtfbreak_unittest.cpp
index 5860add..6c999f1 100644
--- a/xfa/fgas/layout/cfgas_rtfbreak_unittest.cpp
+++ b/xfa/fgas/layout/cfgas_rtfbreak_unittest.cpp
@@ -20,7 +20,12 @@
 class CFGAS_RTFBreakTest : public testing::Test {
  public:
   void SetUp() override {
-    font_ = CFGAS_GEFont::LoadFont(L"Arial Black", 0, FX_CodePage::kDefANSI);
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+    const wchar_t kFontFamily[] = L"Arimo Bold";
+#else
+    const wchar_t kFontFamily[] = L"Arial Bold";
+#endif
+    font_ = CFGAS_GEFont::LoadFont(kFontFamily, 0, FX_CodePage::kDefANSI);
     ASSERT_TRUE(font_);
   }
 
diff --git a/xfa/fgas/layout/cfgas_txtbreak_unittest.cpp b/xfa/fgas/layout/cfgas_txtbreak_unittest.cpp
index 743a9ab..c9f0d0f 100644
--- a/xfa/fgas/layout/cfgas_txtbreak_unittest.cpp
+++ b/xfa/fgas/layout/cfgas_txtbreak_unittest.cpp
@@ -17,7 +17,12 @@
 class CFGAS_TxtBreakTest : public testing::Test {
  public:
   void SetUp() override {
-    font_ = CFGAS_GEFont::LoadFont(L"Arial Black", 0, FX_CodePage::kDefANSI);
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+    const wchar_t kFontFamily[] = L"Arimo Bold";
+#else
+    const wchar_t kFontFamily[] = L"Arial Bold";
+#endif
+    font_ = CFGAS_GEFont::LoadFont(kFontFamily, 0, FX_CodePage::kDefANSI);
     ASSERT_TRUE(font_);
   }