Use third_party/fast_float to convert strings to floats/doubles instead

The existing implementation of StringTo() rounds to the incorrect
float/double value for values with precision error.

Replace the implementation to use third_party/fast_float, which fixes
the rounding error, is easier to read, and is supposedly fast.

Update pixel tests and checksums. There should be little to no visible
differences in the PDFs.

Bug: 364338789, 366309453
Change-Id: I51f4aa9b7fa7a53306d8a2bd604547cfb079eb30
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/124412
Commit-Queue: Andy Phan <andyphan@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/DEPS b/DEPS
index 15ccc6e..93aa97d 100644
--- a/DEPS
+++ b/DEPS
@@ -178,7 +178,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling pdfium_tests
   # and whatever else without interference from each other.
-  'pdfium_tests_revision': '687c70fa09d92782a44516a7aa0a382881da277b',
+  'pdfium_tests_revision': '7e9430c92e07cf45bd151bd4158a7795d117ffeb',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling resultdb
   # and whatever else without interference from each other.
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
index c36e2b7..75d7fe7 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
@@ -443,6 +443,6 @@
   generator.ProcessPageObjects(&process_buf);
   EXPECT_EQ(
       "q 3.102 4.6700001 m 5.4500012 .28999999 l 4.2399998 3.14"
-      "99999 4.6500001 2.98 3.4560001 .24000001 c 3.102 4.6700001 l h f Q\n",
+      "99999 4.6500001 2.98 3.4560001 .23999999 c 3.102 4.6700001 l h f Q\n",
       ByteString(process_buf));
 }
diff --git a/core/fpdfapi/render/fpdf_progressive_render_embeddertest.cpp b/core/fpdfapi/render/fpdf_progressive_render_embeddertest.cpp
index b6c40c7..0d6b92c 100644
--- a/core/fpdfapi/render/fpdf_progressive_render_embeddertest.cpp
+++ b/core/fpdfapi/render/fpdf_progressive_render_embeddertest.cpp
@@ -449,14 +449,14 @@
   const char* content_with_ink_checksum = []() {
     if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
 #if BUILDFLAG(IS_WIN)
-      return "cddb7472b064782b2866aa3dc87ca73e";
+      return "0b9e2044a71465ed8af639527c3cc94a";
 #elif BUILDFLAG(IS_APPLE)
-      return "0ef02da77fc1e08455148ecadd257e06";
+      return "62c1dddb6440dd8180abf51d986141e4";
 #else
-      return "bd9d457356dba5fcf33ec9afdaefcab8";
+      return "32678124d0789c09aa61028de3a8cbcf";
 #endif
     }
-    return "797bce7dc6c50ee86b095405df9fe5aa";
+    return "546c99e50c4f2c66fc7ac02e1a834e57";
   }();
 
   ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
@@ -471,17 +471,17 @@
   const char* content_with_stamp_checksum = []() {
     if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
 #if BUILDFLAG(IS_WIN)
-      return "c35d1256f6684da13023a0e74622c885";
+      return "7e4d84b094fc44094e647803572ae49a";
 #elif BUILDFLAG(IS_APPLE)
-      return "bb302d8808633fede3b6e2e39ac8aaa7";
+      return "f1f1288805d1afd93397c2f24080b741";
 #else
-      return "1bd68054628cf193b399a16638ecb5f9";
+      return "4e42fb3e87ff8276a549d7a755997766";
 #endif
     }
 #if BUILDFLAG(IS_APPLE)
-    return "8170c539e95f22f14eb8f266a5f1bbed";
+    return "ed794dc3e110ddb60aab788bd3d63598";
 #else
-    return "d1fd087e59d4dcebf47b56570bdb8c22";
+    return "f61b2f70101073cc9e8905e16e3923ed";
 #endif
   }();
 
diff --git a/core/fxcrt/BUILD.gn b/core/fxcrt/BUILD.gn
index 6479f8d..21060a4 100644
--- a/core/fxcrt/BUILD.gn
+++ b/core/fxcrt/BUILD.gn
@@ -146,6 +146,7 @@
     "../../:pdfium_strict_config",
     "../../:pdfium_noshorten_config",
   ]
+  deps = [ "//third_party/fast_float" ]
   public_deps = [
     "../../:freetype_common",
     "//third_party/abseil-cpp:absl",
diff --git a/core/fxcrt/DEPS b/core/fxcrt/DEPS
index 2e9180b..f693bd1 100644
--- a/core/fxcrt/DEPS
+++ b/core/fxcrt/DEPS
@@ -2,3 +2,9 @@
   '+partition_alloc',
   '+third_party/icu',
 ]
+
+specific_include_rules = {
+  'fx_string.cpp': [
+    '+third_party/fast_float/src/include/fast_float/fast_float.h',
+  ],
+}
diff --git a/core/fxcrt/fx_string.cpp b/core/fxcrt/fx_string.cpp
index 948c255..1443c29 100644
--- a/core/fxcrt/fx_string.cpp
+++ b/core/fxcrt/fx_string.cpp
@@ -19,6 +19,7 @@
 #include "core/fxcrt/span.h"
 #include "core/fxcrt/utf16.h"
 #include "core/fxcrt/widestring.h"
+#include "third_party/fast_float/src/include/fast_float/fast_float.h"
 
 #if !defined(WCHAR_T_IS_16_BIT) && !defined(WCHAR_T_IS_32_BIT)
 #error "Unknown wchar_t size"
@@ -98,60 +99,36 @@
 
 namespace {
 
-constexpr float kFractionScalesFloat[] = {
-    0.1f,         0.01f,         0.001f,        0.0001f,
-    0.00001f,     0.000001f,     0.0000001f,    0.00000001f,
-    0.000000001f, 0.0000000001f, 0.00000000001f};
-
-const double kFractionScalesDouble[] = {
-    0.1,       0.01,       0.001,       0.0001,       0.00001,      0.000001,
-    0.0000001, 0.00000001, 0.000000001, 0.0000000001, 0.00000000001};
-
 template <class T>
-T StringTo(ByteStringView strc, pdfium::span<const T> fractional_scales) {
-  if (strc.IsEmpty())
-    return 0;
-
-  bool bNegative = false;
-  size_t cc = 0;
+T StringTo(ByteStringView strc) {
+  // Skip leading whitespaces.
+  size_t start = 0;
   size_t len = strc.GetLength();
-  if (strc[0] == '+') {
-    cc++;
-  } else if (strc[0] == '-') {
-    bNegative = true;
-    cc++;
+  while (start < len && strc[start] == ' ') {
+    ++start;
   }
-  while (cc < len) {
-    if (strc[cc] != '+' && strc[cc] != '-')
-      break;
-    cc++;
+
+  // Skip a leading '+' sign.
+  if (start < len && strc[start] == '+') {
+    ++start;
   }
-  T value = 0;
-  while (cc < len) {
-    if (strc[cc] == '.')
-      break;
-    value = value * 10 + FXSYS_DecimalCharToInt(strc.CharAt(cc));
-    cc++;
-  }
-  size_t scale = 0;
-  if (cc < len && strc[cc] == '.') {
-    cc++;
-    while (cc < len) {
-      value +=
-          fractional_scales[scale] * FXSYS_DecimalCharToInt(strc.CharAt(cc));
-      scale++;
-      if (scale == fractional_scales.size())
-        break;
-      cc++;
-    }
-  }
-  return bNegative ? -value : value;
+
+  ByteStringView sub_strc = strc.Substr(start, len - start);
+
+  T value;
+  auto result = fast_float::from_chars(sub_strc.begin(), sub_strc.end(), value);
+
+  // Return 0 for parsing errors. Some examples of errors are an empty string
+  // and a string that cannot be converted to T.
+  return result.ec == std::errc() || result.ec == std::errc::result_out_of_range
+             ? value
+             : 0;
 }
 
 }  // namespace
 
 float StringToFloat(ByteStringView strc) {
-  return StringTo<float>(strc, kFractionScalesFloat);
+  return StringTo<float>(strc);
 }
 
 float StringToFloat(WideStringView wsStr) {
@@ -159,7 +136,7 @@
 }
 
 double StringToDouble(ByteStringView strc) {
-  return StringTo<double>(strc, kFractionScalesDouble);
+  return StringTo<double>(strc);
 }
 
 double StringToDouble(WideStringView wsStr) {
diff --git a/core/fxcrt/fx_string_unittest.cpp b/core/fxcrt/fx_string_unittest.cpp
index 601deb2..b9e74e3 100644
--- a/core/fxcrt/fx_string_unittest.cpp
+++ b/core/fxcrt/fx_string_unittest.cpp
@@ -76,8 +76,7 @@
 
   EXPECT_FLOAT_EQ(0.25f, StringToFloat(L"+0.25"));
 
-  // TODO(crbug.com/367395351): Should be 1.2e34f.
-  EXPECT_FLOAT_EQ(1.2034f, StringToFloat("1.2e34"));
+  EXPECT_FLOAT_EQ(1.2e34f, StringToFloat("1.2e34"));
 
   EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
                   StringToFloat("999999999999999999999999999999999999999"));
@@ -88,8 +87,7 @@
 
   // Test the exact float value. Use EXPECT_EQ, which does an exact comparison,
   // instead of EXPECT_FLOAT_EQ, which allows slight precision error.
-  // TODO(crbug.com/366309453): Should round to 38.89528656005859375f.
-  EXPECT_EQ(38.895282745361328125f, StringToFloat("38.895285"));
+  EXPECT_EQ(38.89528656005859375f, StringToFloat("38.895285"));
 }
 
 TEST(fxstring, WideStringToFloat) {
@@ -116,8 +114,7 @@
 
   EXPECT_FLOAT_EQ(0.25f, StringToFloat(L"+0.25"));
 
-  // TODO(crbug.com/367395351): Should be 1.2e34f.
-  EXPECT_FLOAT_EQ(1.2034f, StringToFloat(L"1.2e34"));
+  EXPECT_FLOAT_EQ(1.2e34f, StringToFloat(L"1.2e34"));
 
   EXPECT_FLOAT_EQ(std::numeric_limits<float>::infinity(),
                   StringToFloat(L"999999999999999999999999999999999999999"));
@@ -128,8 +125,7 @@
 
   // Test the exact float value. Use EXPECT_EQ, which does an exact comparison,
   // instead of EXPECT_FLOAT_EQ, which allows slight precision error.
-  // TODO(crbug.com/366309453): Should round to 38.89528656005859375f.
-  EXPECT_EQ(38.895282745361328125f, StringToFloat(L"38.895285"));
+  EXPECT_EQ(38.89528656005859375f, StringToFloat(L"38.895285"));
 }
 
 TEST(fxstring, ByteStringToDouble) {
@@ -156,8 +152,7 @@
 
   EXPECT_DOUBLE_EQ(0.25, StringToDouble("+0.25"));
 
-  // TODO(crbug.com/367395351): Should be 1.2e34.
-  EXPECT_DOUBLE_EQ(1.2034, StringToDouble("1.2e34"));
+  EXPECT_DOUBLE_EQ(1.2e34, StringToDouble("1.2e34"));
 
   EXPECT_DOUBLE_EQ(
       std::numeric_limits<double>::infinity(),
@@ -180,8 +175,7 @@
 
   // Test the exact double value. Use EXPECT_EQ, which does an exact comparison,
   // instead of EXPECT_DOUBLE_EQ, which allows slight precision error.
-  // TODO(crbug.com/366309453): Should round to 1.9998779296892903.
-  EXPECT_EQ(1.9998779296800002, StringToDouble("1.99987792968929034"));
+  EXPECT_EQ(1.9998779296892903, StringToDouble("1.99987792968929034"));
 }
 
 TEST(fxstring, WideStringToDouble) {
@@ -208,8 +202,7 @@
 
   EXPECT_DOUBLE_EQ(0.25, StringToDouble(L"+0.25"));
 
-  // TODO(crbug.com/367395351): Should be 1.2e34.
-  EXPECT_DOUBLE_EQ(1.2034, StringToDouble(L"1.2e34"));
+  EXPECT_DOUBLE_EQ(1.2e34, StringToDouble(L"1.2e34"));
 
   EXPECT_DOUBLE_EQ(
       std::numeric_limits<double>::infinity(),
@@ -232,8 +225,7 @@
 
   // Test the exact double value. Use EXPECT_EQ, which does an exact comparison,
   // instead of EXPECT_DOUBLE_EQ, which allows slight precision error.
-  // TODO(crbug.com/366309453): Should round to 1.9998779296892903.
-  EXPECT_EQ(1.9998779296800002, StringToDouble(L"1.99987792968929034"));
+  EXPECT_EQ(1.9998779296892903, StringToDouble(L"1.99987792968929034"));
 }
 
 TEST(fxstring, SplitByteString) {
diff --git a/fpdfsdk/fpdf_annot_embeddertest.cpp b/fpdfsdk/fpdf_annot_embeddertest.cpp
index 7a36b97..9244a04 100644
--- a/fpdfsdk/fpdf_annot_embeddertest.cpp
+++ b/fpdfsdk/fpdf_annot_embeddertest.cpp
@@ -496,8 +496,8 @@
     ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot.get(), 0, &quadpoints));
     EXPECT_EQ(115.802643f, quadpoints.x1);
     EXPECT_EQ(718.913940f, quadpoints.y1);
-    EXPECT_EQ(157.211182f, quadpoints.x4);
-    EXPECT_EQ(706.264465f, quadpoints.y4);
+    EXPECT_EQ(157.211166f, quadpoints.x4);
+    EXPECT_EQ(706.264404f, quadpoints.y4);
   }
   UnloadPageNoEvents(page);
 }
@@ -537,23 +537,23 @@
     // Note that upon rendering, the rectangle coordinates will be adjusted.
     FS_RECTF rect;
     ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
-    EXPECT_EQ(351.820404f, rect.left);
-    EXPECT_EQ(583.830688f, rect.bottom);
-    EXPECT_EQ(475.336090f, rect.right);
+    EXPECT_EQ(351.820435f, rect.left);
+    EXPECT_EQ(583.830750f, rect.bottom);
+    EXPECT_EQ(475.336121f, rect.right);
     EXPECT_EQ(681.535034f, rect.top);
   }
   {
     const char* expected_hash = []() {
       if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
 #if BUILDFLAG(IS_WIN)
-        return "b4698da8e2f9e8cb82b7bbb6e7d559a9";
+        return "42e03089ef2392579d73bf9065896488";
 #elif BUILDFLAG(IS_APPLE)
-        return "e3da57011a3d66238d15be1bedcb6696";
+        return "5891aa346046c3f5b8c3cd8607f0d256";
 #else
-        return "c2404a7a9a86ee78487cd1993949c56d";
+        return "d02d468d9022ddf35014daa50191a895";
 #endif
       }
-      return "354002e1c4386d38fdde29ef8d61074a";
+      return "738a3881cb2cfb3e69e2a3adbc7c1d5b";
     }();
     ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
     CompareBitmap(bitmap.get(), 612, 792, expected_hash);
@@ -750,8 +750,8 @@
     ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot.get(), 0, &quadpoints));
     EXPECT_EQ(115.802643f, quadpoints.x1);
     EXPECT_EQ(718.913940f, quadpoints.y1);
-    EXPECT_EQ(157.211182f, quadpoints.x4);
-    EXPECT_EQ(706.264465f, quadpoints.y4);
+    EXPECT_EQ(157.211166f, quadpoints.x4);
+    EXPECT_EQ(706.264404f, quadpoints.y4);
   }
 
   // Add an underline annotation to the page and set its quadpoints.
@@ -926,11 +926,11 @@
   const char* md5_modified_square = []() {
     if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
 #if BUILDFLAG(IS_WIN)
-      return "cebb3bd3209f63f6dfd15b8425229e90";
+      return "25bb74224a3519a397a8b987069085a5";
 #elif BUILDFLAG(IS_APPLE)
-      return "613102f8b6d74d6d9f95c8eacd17b756";
+      return "8b9df3824179d3757932bda23b95c8ce";
 #else
-      return "879c77a2cb9f79ba65ffe0bbdd720ce3";
+      return "4f66924b2d246f9e8a1b926e956b615b";
 #endif
     }
 #if BUILDFLAG(IS_APPLE)
@@ -1130,49 +1130,49 @@
   const char* md5_modified_path = []() {
     if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
 #if BUILDFLAG(IS_WIN)
-      return "c8ae5b9ebd9982d9fde526f50f936971";
+      return "02c0628d5e1da4d0f2d481272c7e5a9b";
 #elif BUILDFLAG(IS_APPLE)
-      return "3adf48360ca55e8794a9fc9f1ea87df1";
+      return "c81ee833f81ae0fa674e0c16872156d2";
 #else
-      return "94f7f4568385c16498604ddc46f18be9";
+      return "4a3a53f2b1b0cb40e9a32305eef9197a";
 #endif
     }
 #if BUILDFLAG(IS_APPLE)
-    return "34614087e04b729b7b8c37739dcf9af9";
+    return "ac6a1526c71bb0cebe3c3c0b6bf59aab";
 #else
-    return "31a94d22460171cd83169daf6a6956ee";
+    return "fb9e6f707986e5daf2f7bb75b4ed28ec";
 #endif
   }();
   const char* md5_two_paths = []() {
     if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
 #if BUILDFLAG(IS_WIN)
-      return "d29d4258bd9344abf20bb55e6679c065";
+      return "cf7119f478a5daf7fa7c707514f39e13";
 #elif BUILDFLAG(IS_APPLE)
-      return "5f7d44d3a4ffaadb6bf20b4f1ac2a1f0";
+      return "c3ce00fda0bcaad52536b49991a24aba";
 #else
-      return "1052cd0fe1c3e73865fc842525245551";
+      return "db4c609adaa0dcfba213450bbd62264e";
 #endif
     }
 #if BUILDFLAG(IS_APPLE)
-    return "6cdaf6b3e5145f435d8ccae6db5cf9af";
+    return "48a03185099a335f60b158ade04ff22c";
 #else
-    return "ed49fefef45f14121f8150cde10006c4";
+    return "1abd24eb0ec89cd429ea7080d9762713";
 #endif
   }();
   const char* md5_new_annot = []() {
     if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
 #if BUILDFLAG(IS_WIN)
-      return "9ca0a274d1ae0db09ad814ee455dd88c";
+      return "df816a3ea0b92e597fa04e8a0a80e5a7";
 #elif BUILDFLAG(IS_APPLE)
-      return "71c8fb8eee9720c19851c48745dde152";
+      return "75f8d0866cda9bc7545a9c1162841aad";
 #else
-      return "f522e1262f487cc1976bb3fc585ef469";
+      return "d4d1b116d5f23dfec894e25db4c5ebdb";
 #endif
     }
 #if BUILDFLAG(IS_APPLE)
-    return "e6015f42eb81ed6003224cb2f27dcb51";
+    return "eae62b0038343c77141eedea842f01eb";
 #else
-    return "2e567a33390cd2ebad9dc33d82a8b054";
+    return "897415260f33a8b553c85466ffcf4a56";
 #endif
   }();
 
@@ -1373,33 +1373,33 @@
   const char* md5_new_image = []() {
     if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
 #if BUILDFLAG(IS_WIN)
-      return "3515dee02973f010516e4c6c774ee281";
+      return "795cf0ce02f6f2d3a23ed06a148af82f";
 #elif BUILDFLAG(IS_APPLE)
-      return "f740480598ff3732fb31871634509eec";
+      return "617f9f6f00167f83e9ffb31751624a9e";
 #else
-      return "77bf1781c60370bfcd8d81cf91ab7b09";
+      return "5526f05092a0253d56a0e79e0e104f71";
 #endif
     }
 #if BUILDFLAG(IS_APPLE)
-    return "17ac49518eabbb6a7632a547269c40a3";
+    return "4c63afd81a7835579485f056e2d5f951";
 #else
-    return "e79446398d4508bc2cb47e6cf2a677ed";
+    return "727380057983d1ce10c7f51cbcd0917f";
 #endif
   }();
   const char* md5_modified_image = []() {
     if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
 #if BUILDFLAG(IS_WIN)
-      return "aeb7cfb0bf6ac2bcdef4412276f3bad4";
+      return "7c33121197cf13a83b96e913d70fe12d";
 #elif BUILDFLAG(IS_APPLE)
-      return "5beae8949ee6b5c99fe17475e90aea02";
+      return "0bd1b3bbefa3bae4199ce9c8b5bf840b";
 #else
-      return "cfa8aa132250a1c0fec505bd13c15916";
+      return "e3f115b37181ce0ffd02c7b5288ea99a";
 #endif
     }
 #if BUILDFLAG(IS_APPLE)
-    return "25bf5ec7c197cf9ff3d12b41fc336b25";
+    return "5d242652769254acd9a1f91311ff6b65";
 #else
-    return "dcb492d8e32528dd81bb60fa5bc900f8";
+    return "f0d4f77fee46e77f79edae2d93d574a3";
 #endif
   }();
 
@@ -1481,37 +1481,37 @@
   const char* md5_new_text = []() {
     if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
 #if BUILDFLAG(IS_WIN)
-      return "9fbad802120d58b2b8b7edd043eeaf55";
+      return "d9b4f92933bbde80a123048ae2ef7296";
 #elif BUILDFLAG(IS_APPLE)
-      return "eefdf26393df536e7f125816e7d967ff";
+      return "f63c9d35c6c19f88ffb92471e97b7e22";
 #else
-      return "f89c413c7155ae9b4a0b7c8e4013613e";
+      return "6b1cfec7e9c89da93dc14172afffc5db";
 #endif
     }
 #if BUILDFLAG(IS_APPLE) && defined(ARCH_CPU_ARM64)
     return "8eabf79dcdcfc6474c593bc60d996def";
 #elif BUILDFLAG(IS_APPLE) && !defined(ARCH_CPU_ARM64)
-    return "5d449d36926c9f212c6cdb6c276d18cc";
+    return "8cfa6f61f5a03b3f2306d0924ef6c000";
 #else
-    return "a9532f555aca2fd099e2107fa40b61e6";
+    return "c9b2be9f9bcb8998ee181f149a979cb8";
 #endif
   }();
   const char* md5_modified_text = []() {
     if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
 #if BUILDFLAG(IS_WIN)
-      return "850564e273ad58f651af09d880103e82";
+      return "a393718c0bc2144131e3c60b51cd985c";
 #elif BUILDFLAG(IS_APPLE)
-      return "25c03a641c8a7cac9845f8d38e54f90b";
+      return "76b7f0cb6f0e52aa25a2c1e11c9abd62";
 #else
-      return "707320c806ed846c73ca2be8b2328bcd";
+      return "007960dd422d0999f71a9de0faa29b07";
 #endif
     }
 #if BUILDFLAG(IS_APPLE) && defined(ARCH_CPU_ARM64)
     return "704f3eb56f82377753a816a43de250ea";
 #elif BUILDFLAG(IS_APPLE) && !defined(ARCH_CPU_ARM64)
-    return "8c992808db99dbe3d74006358a671f05";
+    return "c39124df1815dd6fce3b2f113169c8c9";
 #else
-    return "03cae68322d6a6ba120e738ab325408c";
+    return "c08913614721f4337ff893c3cf53026d";
 #endif
   }();
 
@@ -1642,17 +1642,17 @@
   const char* md5 = []() {
     if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
 #if BUILDFLAG(IS_WIN)
-      return "25b2a610cab9d656b9ab5f72746c9e2e";
+      return "d0dfc003b3e08160e698355b599f7eb8";
 #elif BUILDFLAG(IS_APPLE)
-      return "0f6501f8e22441630bdd535363c93e59";
+      return "8774ac1779ea66056860290ae7df8f44";
 #else
-      return "1814140b1a9a9776546af7894e21d17f";
+      return "8b8618de537ec6aee1f3fc53fedfbcfc";
 #endif
     }
 #if BUILDFLAG(IS_APPLE)
-    return "0521eaa52fe2aa43aafd3e4495f63f0b";
+    return "587311ad93447614cbe5887df14caa78";
 #else
-    return "5f19ddad9d48f5b7b87ee7d92f577db6";
+    return "2908fd6166f795dfd73c607ec12c5356";
 #endif
   }();
 
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp
index 8cae5c3..57680a1 100644
--- a/fpdfsdk/fpdf_edit_embeddertest.cpp
+++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -614,9 +614,9 @@
   {
     const char* last_checksum = []() {
       if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
-        return "423b20c18c177e78c93d8b67594e49f1";
+        return "ed14c60702b1489c597c7d46ece7f86d";
       }
-      return "111c38e9bf9e2ba0a57b875cca596fff";
+      return "9823e1a21bd9b72b6a442ba4f12af946";
     }();
     VerifySavedDocument(612, 792, last_checksum);
   }
@@ -1448,7 +1448,7 @@
 #ifdef ARCH_CPU_ARM64
       return "401858d37db450bfd3f9458ac490eb08";
 #else
-      return "966579fb98206858ce2f0a1f94a74d05";
+      return "6275396f29951f92f8f5e145f0eff03a";
 #endif  // ARCH_CPU_ARM64
 #else
       return "3d5a3de53d5866044c2b6bf339742c97";
@@ -1505,7 +1505,7 @@
 #ifdef ARCH_CPU_ARM64
     return "6a1e31ffe451997946e449250b97d5b2";
 #else
-    return "6e19a4dd674b522cd39cf41956559bd6";
+    return "631be723d5ff1f36e75c971cc940351b";
 #endif  // ARCH_CPU_ARM64
 #else
     return "bc8623c052f12376c3d8dd09a6cd27df";
@@ -1525,7 +1525,7 @@
 #ifdef ARCH_CPU_ARM64
     return "d250bee3658c74e5d74729a09cbd80cd";
 #else
-    return "3cb35c681f8fb5a43a49146ac7caa818";
+    return "631be723d5ff1f36e75c971cc940351b";
 #endif  // ARCH_CPU_ARM64
 #else
     return "bc8623c052f12376c3d8dd09a6cd27df";
@@ -1975,7 +1975,7 @@
 #if ARCH_CPU_ARM64
     return "a47297bbcfa01e27891eeb52375b6f9e";
 #else
-    return "3cdc75af44c15bed80998facd6e674c9";
+    return "1c1d478b59e3e63813f0f56124564f48";
 #endif  // ARCH_CPU_ARM64
 #else
     return "b474826df1acedb05c7b82e1e49e64a6";
diff --git a/fpdfsdk/fpdf_save_embeddertest.cpp b/fpdfsdk/fpdf_save_embeddertest.cpp
index e3d8947..16dc4ae 100644
--- a/fpdfsdk/fpdf_save_embeddertest.cpp
+++ b/fpdfsdk/fpdf_save_embeddertest.cpp
@@ -152,7 +152,7 @@
   EXPECT_THAT(GetString(), HasSubstr("36 0 obj"));
   EXPECT_THAT(GetString(), Not(HasSubstr("37 0 obj")));
   EXPECT_THAT(GetString(), Not(HasSubstr("38 0 obj")));
-  EXPECT_EQ(7996u, GetString().size());
+  EXPECT_EQ(7986u, GetString().size());
 
   // Make sure new document renders the same as the old one.
   ASSERT_TRUE(OpenSavedDocument());
diff --git a/testing/embedder_test_constants.cpp b/testing/embedder_test_constants.cpp
index 551710d..f0279ae 100644
--- a/testing/embedder_test_constants.cpp
+++ b/testing/embedder_test_constants.cpp
@@ -12,17 +12,17 @@
 const char* AnnotationStampWithApChecksum() {
   if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
 #if BUILDFLAG(IS_WIN)
-    return "25b2a610cab9d656b9ab5f72746c9e2e";
+    return "d0dfc003b3e08160e698355b599f7eb8";
 #elif BUILDFLAG(IS_APPLE)
-    return "0f6501f8e22441630bdd535363c93e59";
+    return "8774ac1779ea66056860290ae7df8f44";
 #else
-    return "1814140b1a9a9776546af7894e21d17f";
+    return "8b8618de537ec6aee1f3fc53fedfbcfc";
 #endif
   }
 #if BUILDFLAG(IS_APPLE)
-  return "0521eaa52fe2aa43aafd3e4495f63f0b";
+  return "587311ad93447614cbe5887df14caa78";
 #else
-  return "5f19ddad9d48f5b7b87ee7d92f577db6";
+  return "2908fd6166f795dfd73c607ec12c5356";
 #endif
 }
 
diff --git a/testing/resources/pixel/bug_1330_expected.pdf.0.png b/testing/resources/pixel/bug_1330_expected.pdf.0.png
index 134f8bb..79f011a 100644
--- a/testing/resources/pixel/bug_1330_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_1330_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_736695_1_expected.pdf.0.png b/testing/resources/pixel/bug_736695_1_expected.pdf.0.png
index 10bbb0d..4673ede 100644
--- a/testing/resources/pixel/bug_736695_1_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_736695_1_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_736695_1_expected_skia.pdf.0.png b/testing/resources/pixel/bug_736695_1_expected_skia.pdf.0.png
index aa030a1..2850e96 100644
--- a/testing/resources/pixel/bug_736695_1_expected_skia.pdf.0.png
+++ b/testing/resources/pixel/bug_736695_1_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_736695_4_expected.pdf.0.png b/testing/resources/pixel/bug_736695_4_expected.pdf.0.png
index 10bbb0d..4673ede 100644
--- a/testing/resources/pixel/bug_736695_4_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_736695_4_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_736695_4_expected_skia.pdf.0.png b/testing/resources/pixel/bug_736695_4_expected_skia.pdf.0.png
index aa030a1..2850e96 100644
--- a/testing/resources/pixel/bug_736695_4_expected_skia.pdf.0.png
+++ b/testing/resources/pixel/bug_736695_4_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/radial_shading_point_at_center_expected.pdf.0.png b/testing/resources/pixel/radial_shading_point_at_center_expected.pdf.0.png
index c69c190..f7a6300 100644
--- a/testing/resources/pixel/radial_shading_point_at_center_expected.pdf.0.png
+++ b/testing/resources/pixel/radial_shading_point_at_center_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/radial_shading_point_at_center_expected_skia.pdf.0.png b/testing/resources/pixel/radial_shading_point_at_center_expected_skia.pdf.0.png
index 756ddb8..dbc4031 100644
--- a/testing/resources/pixel/radial_shading_point_at_center_expected_skia.pdf.0.png
+++ b/testing/resources/pixel/radial_shading_point_at_center_expected_skia.pdf.0.png
Binary files differ