[Skia] Fix the issue that texts are rendered narrower than expected.

When Skia/SkiaPaths is enabled, render a substituted glyph using its
path instead of using CFX_SkiaDeviceDriver when its width defined in
the PDF is narrower than the default glyph width.

This CL also update the expectations of the embedder tests, pixel tests
and corpus tests which are affected by this change.

Bug: pdfium:1752
Change-Id: If0f990fb4eaeda509a74b33d8086e4b8e69cf074
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/91213
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Nigi <nigi@chromium.org>
diff --git a/core/fpdfapi/render/fpdf_progressive_render_embeddertest.cpp b/core/fpdfapi/render/fpdf_progressive_render_embeddertest.cpp
index e337aeb..bb68391 100644
--- a/core/fpdfapi/render/fpdf_progressive_render_embeddertest.cpp
+++ b/core/fpdfapi/render/fpdf_progressive_render_embeddertest.cpp
@@ -384,7 +384,7 @@
 // Normal blend mode.
 #if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
   static constexpr char kContentWithHighlightFillChecksum[] =
-      "fa25846c61d0253e86e8512d3be06ebb";
+      "1ad601278736432e2f82ea37ab6a28ba";
 #else
 #if BUILDFLAG(IS_APPLE)
   static constexpr char kContentWithHighlightFillChecksum[] =
@@ -413,12 +413,12 @@
 #endif
 TEST_F(FPDFProgressiveRenderEmbedderTest,
        MAYBE_RenderHighlightWithColorSchemeAndConvertFillToStroke) {
-// Test rendering of highlight with forced color and converting fill to
-// stroke. The highlight should be rendered as a stroke of the rect.
-//
-// Note: The stroke color rendered for highlight is different from the normal
-// path since highlights have Multiply blend mode, while the other path has
-// Normal blend mode.
+  // Test rendering of highlight with forced color and converting fill to
+  // stroke. The highlight should be rendered as a stroke of the rect.
+  //
+  // Note: The stroke color rendered for highlight is different from the normal
+  // path since highlights have Multiply blend mode, while the other path has
+  // Normal blend mode.
 #if BUILDFLAG(IS_APPLE)
   static constexpr char kMD5ContentWithHighlight[] =
       "8837bea0b3520164b1784e513c882a2d";
@@ -446,14 +446,9 @@
 TEST_F(FPDFProgressiveRenderEmbedderTest, MAYBE_RenderInkWithColorScheme) {
 // Test rendering of multiple ink with forced color scheme on.
 #if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
-#if BUILDFLAG(IS_APPLE)
   static constexpr char kContentWithInkChecksum[] =
       "ebc57721e4c8da34156e09b9b2e62fb0";
 #else
-  static constexpr char kContentWithInkChecksum[] =
-      "b39d9f68ff71963d82c43eb20caa8f4d";
-#endif  // BUILDFLAG(IS_APPLE)
-#else
 #if BUILDFLAG(IS_WIN)
   static constexpr char kContentWithInkChecksum[] =
       "1933e4ab19b9108ddcecd1a6abb20c85";
diff --git a/core/fxge/cfx_font.cpp b/core/fxge/cfx_font.cpp
index 8b3a727..4df6de4 100644
--- a/core/fxge/cfx_font.cpp
+++ b/core/fxge/cfx_font.cpp
@@ -410,11 +410,17 @@
   }
 }
 
-int CFX_Font::GetGlyphWidth(uint32_t glyph_index) {
+int CFX_Font::GetGlyphWidth(uint32_t glyph_index) const {
+  return GetGlyphWidth(glyph_index, 0, 0);
+}
+
+int CFX_Font::GetGlyphWidth(uint32_t glyph_index,
+                            int dest_width,
+                            int weight) const {
   if (!m_Face)
     return 0;
   if (m_pSubstFont && m_pSubstFont->m_bFlagMM)
-    AdjustMMParams(glyph_index, 0, 0);
+    AdjustMMParams(glyph_index, dest_width, weight);
   int err =
       FT_Load_Glyph(m_Face->GetRec(), glyph_index,
                     FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
diff --git a/core/fxge/cfx_font.h b/core/fxge/cfx_font.h
index b506f36..71ecaad 100644
--- a/core/fxge/cfx_font.h
+++ b/core/fxge/cfx_font.h
@@ -104,7 +104,8 @@
       int anti_alias,
       CFX_TextRenderOptions* text_options) const;
   const CFX_Path* LoadGlyphPath(uint32_t glyph_index, int dest_width) const;
-  int GetGlyphWidth(uint32_t glyph_index);
+  int GetGlyphWidth(uint32_t glyph_index) const;
+  int GetGlyphWidth(uint32_t glyph_index, int dest_width, int weight) const;
   int GetAscent() const;
   int GetDescent() const;
   absl::optional<FX_RECT> GetGlyphBBox(uint32_t glyph_index);
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index 742c260..cc5bbf1 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -31,6 +31,7 @@
 #include "core/fxge/cfx_graphstatedata.h"
 #include "core/fxge/cfx_path.h"
 #include "core/fxge/cfx_renderdevice.h"
+#include "core/fxge/cfx_substfont.h"
 #include "core/fxge/cfx_textrenderoptions.h"
 #include "core/fxge/dib/cfx_bitmapcomposer.h"
 #include "core/fxge/dib/cfx_dibitmap.h"
@@ -1039,17 +1040,7 @@
       skCanvas->drawTextBlob(blob, 0, 0, skPaint);
     } else {
       const SkTDArray<SkPoint>& positions = m_charDetails.GetPositions();
-      const SkTDArray<uint32_t>& widths = m_charDetails.GetFontCharWidths();
       for (int i = 0; i < m_charDetails.Count(); ++i) {
-        uint32_t font_glyph_width =
-            m_pFont ? m_pFont->GetGlyphWidth(glyphs[i]) : 0;
-        uint32_t pdf_glyph_width = widths[i];
-        if (font_glyph_width && pdf_glyph_width &&
-            font_glyph_width > pdf_glyph_width) {
-          font.setScaleX(SkIntToScalar(pdf_glyph_width) / font_glyph_width);
-        } else {
-          font.setScaleX(SkIntToScalar(1));
-        }
         sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText(
             &glyphs[i], sizeof(glyphs[i]), font, SkTextEncoding::kGlyphID);
         skCanvas->drawTextBlob(blob, positions[i].fX, positions[i].fY, skPaint);
@@ -1723,6 +1714,20 @@
     float font_size,
     uint32_t color,
     const CFX_TextRenderOptions& options) {
+  // If a glyph's default width is larger than its width defined in the PDF,
+  // draw the glyph with path since it can be scaled to avoid overlapping with
+  // the adjacent glyphs (if there are any). Otherwise, use the device driver
+  // to render the glyph without any adjustments.
+  const CFX_SubstFont* subst_font = pFont->GetSubstFont();
+  const int subst_font_weight =
+      (subst_font && subst_font->m_bFlagMM) ? subst_font->m_Weight : 0;
+  for (const TextCharPos& cp : pCharPos) {
+    const int glyph_width = pFont->GetGlyphWidth(
+        cp.m_GlyphIndex, cp.m_FontCharWidth, subst_font_weight);
+    if (cp.m_FontCharWidth < glyph_width)
+      return false;
+  }
+
   int nChars = fxcrt::CollectionSize<int>(pCharPos);
   if (m_pCache->DrawText(nChars, pCharPos.data(), pFont, mtObject2Device,
                          font_size, color, options)) {
@@ -1843,16 +1848,6 @@
     }
   } else {
     for (int index = 0; index < nChars; ++index) {
-      const TextCharPos& cp = pCharPos[index];
-      uint32_t font_glyph_width =
-          pFont ? pFont->GetGlyphWidth(cp.m_GlyphIndex) : 0;
-      uint32_t pdf_glyph_width = cp.m_FontCharWidth;
-      if (font_glyph_width && pdf_glyph_width &&
-          font_glyph_width > pdf_glyph_width) {
-        font.setScaleX(SkIntToScalar(pdf_glyph_width) / font_glyph_width);
-      } else {
-        font.setScaleX(SkIntToScalar(1));
-      }
       auto blob =
           SkTextBlob::MakeFromText(&glyphs[index], sizeof(glyphs[index]), font,
                                    SkTextEncoding::kGlyphID);
diff --git a/fpdfsdk/fpdf_annot_embeddertest.cpp b/fpdfsdk/fpdf_annot_embeddertest.cpp
index 31c1c64..5055768 100644
--- a/fpdfsdk/fpdf_annot_embeddertest.cpp
+++ b/fpdfsdk/fpdf_annot_embeddertest.cpp
@@ -543,12 +543,10 @@
     EXPECT_EQ(681.535034f, rect.top);
   }
   {
-#if defined(_SKIA_SUPPORT_) && BUILDFLAG(IS_APPLE)
+#if defined(_SKIA_SUPPORT_)
     static constexpr char kExpectedHash[] = "fad91b9c968fe8019a774f5e2419b8fc";
-#elif defined(_SKIA_SUPPORT_PATHS_) && BUILDFLAG(IS_APPLE)
+#elif defined(_SKIA_SUPPORT_PATHS_)
     static constexpr char kExpectedHash[] = "acddfe688a117ead56af7b249a2cf8a1";
-#elif defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
-    static constexpr char kExpectedHash[] = "1fb0dd8dd5f0b9bb8d076e48eb59296d";
 #elif BUILDFLAG(IS_WIN)
     static constexpr char kExpectedHash[] = "49d0a81c636531a337429325273d0508";
 #else
@@ -770,12 +768,10 @@
   UnloadPage(page);
 
   // Open the saved document.
-#if defined(_SKIA_SUPPORT_) && BUILDFLAG(IS_APPLE)
+#if defined(_SKIA_SUPPORT_)
   static const char kChecksum[] = "899387ae792390cd0d83cf7e2bbebfb5";
-#elif defined(_SKIA_SUPPORT_PATHS_) && BUILDFLAG(IS_APPLE)
+#elif defined(_SKIA_SUPPORT_PATHS_)
   static const char kChecksum[] = "e40e235ee35f47ff28dda009aaaf36df";
-#elif defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
-  static const char kChecksum[] = "798fa41303381c9ba6d99092f5cd4d2b";
 #else
   static const char kChecksum[] = "dba153419f67b7c0c0e3d22d3e8910d5";
 #endif
@@ -899,17 +895,12 @@
 #endif
 TEST_F(FPDFAnnotEmbedderTest, MAYBE_ModifyRectQuadpointsWithAP) {
 #if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
-  static const char kMd5Original[] = "00e70eb543c2a6e8f8aafb4ee951d9bf";
+  static const char kMd5Original[] = "127c2d3b4452555e3317827b0dbbb6a0";
   static const char kMd5ModifiedHighlight[] =
-      "7638c4a8fe4aabbf8704e198f49b3198";
-  static const char kMd5ModifiedSquare[] = "54f507af6af63de877b9cafdab1bbdaa";
+      "6ffe732be6f80540b60921c4803b590a";
+  static const char kMd5ModifiedSquare[] = "9ecbeea7f54abea298b53ce79d301f4a";
 #else
-#if BUILDFLAG(IS_WIN)
-  static const char kMd5Original[] = "0e27376094f11490f74c65f3dc3a42c5";
-  static const char kMd5ModifiedHighlight[] =
-      "66f3caef3a7d488a4fa1ad37fc06310e";
-  static const char kMd5ModifiedSquare[] = "a456dad0bc6801ee2d6408a4394af563";
-#elif BUILDFLAG(IS_APPLE)
+#if BUILDFLAG(IS_APPLE)
   static const char kMd5Original[] = "fc59468d154f397fd298c69f47ef565a";
   static const char kMd5ModifiedHighlight[] =
       "e64bf648f6e9354d1f3eedb47a2c9498";
@@ -919,7 +910,7 @@
   static const char kMd5ModifiedHighlight[] =
       "66f3caef3a7d488a4fa1ad37fc06310e";
   static const char kMd5ModifiedSquare[] = "a456dad0bc6801ee2d6408a4394af563";
-#endif
+#endif  // BUILDFLAG(IS_APPLE)
 #endif  // defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
 
   // Open a file with four annotations and load its first page.
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp
index 56c12ce..2855368 100644
--- a/fpdfsdk/fpdf_edit_embeddertest.cpp
+++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -64,7 +64,7 @@
 const wchar_t kLoadedFontText[] = L"I am testing my loaded font, WEE.";
 
 #if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
-const char kLoadedFontTextChecksum[] = "fc2334c350cbd0d2ae6076689da09741";
+const char kLoadedFontTextChecksum[] = "d58570cc045dfb818b92cbabbd1a364c";
 #elif BUILDFLAG(IS_APPLE)
 const char kLoadedFontTextChecksum[] = "0f3e4a7d71f9e7eb8a1a0d69403b9848";
 #else
@@ -260,15 +260,7 @@
   FPDFPage_InsertObject(page.get(), text_object);
   EXPECT_TRUE(FPDFPage_GenerateContent(page.get()));
 
-#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
-#if BUILDFLAG(IS_APPLE)
   const char kChecksum[] = "9a31fb87d1c6d2346bba22d1196041cd";
-#else   // BUILDFLAG(IS_APPLE)
-  const char kChecksum[] = "5bb65e15fc0a685934cd5006dec08a76";
-#endif  // BUILDFLAG(IS_APPLE)
-#else   // defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
-  const char kChecksum[] = "9a31fb87d1c6d2346bba22d1196041cd";
-#endif  // defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
   ScopedFPDFBitmap page_bitmap = RenderPage(page.get());
   CompareBitmap(page_bitmap.get(), 400, 400, kChecksum);
 
@@ -305,15 +297,7 @@
   FPDFPage_InsertObject(page.get(), text_object);
   EXPECT_TRUE(FPDFPage_GenerateContent(page.get()));
 
-#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
-#if BUILDFLAG(IS_APPLE)
   const char kChecksum[] = "9a31fb87d1c6d2346bba22d1196041cd";
-#else   // BUILDFLAG(IS_APPLE)
-  const char kChecksum[] = "5bb65e15fc0a685934cd5006dec08a76";
-#endif  // BUILDFLAG(IS_APPLE)
-#else   // defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
-  const char kChecksum[] = "9a31fb87d1c6d2346bba22d1196041cd";
-#endif  // defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
   ScopedFPDFBitmap page_bitmap = RenderPage(page.get());
   CompareBitmap(page_bitmap.get(), 400, 400, kChecksum);
 
@@ -3008,7 +2992,7 @@
   }
   ScopedFPDFBitmap page_bitmap2 = RenderPage(page);
 #if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
-  const char kInsertTrueTypeChecksum[] = "4f9a6c7752ac7d4e4c731260fdb5af15";
+  const char kInsertTrueTypeChecksum[] = "683f4a385a891494100192cb338b11f0";
 #elif BUILDFLAG(IS_APPLE)
   const char kInsertTrueTypeChecksum[] = "c7e2271a7f30e5b919a13ead47cea105";
 #else
@@ -3084,11 +3068,7 @@
   }
 
   // Check that the text renders properly.
-#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
-  static constexpr char md5[] = "2e174d17de96a760d42ca3a06acbf36a";
-#else
   static constexpr char md5[] = "84d31d11b76845423a2cfc1879c0fbb9";
-#endif
   {
     ScopedFPDFBitmap page_bitmap = RenderPage(page);
     CompareBitmap(page_bitmap.get(), 612, 792, md5);
diff --git a/testing/SUPPRESSIONS b/testing/SUPPRESSIONS
index ee548b2..8d1be51 100644
--- a/testing/SUPPRESSIONS
+++ b/testing/SUPPRESSIONS
@@ -374,9 +374,6 @@
 # TODO(chromium:725555, skia:9265): Remove after associated bug is fixed
 bug_725555.in * * * skia,skiapaths
 
-# TODO(pdfium:1752): Remove after associated bug is fixed
-bug_845697.in * * * skia,skiapaths
-
 # TODO(pdfium:1749): Remove after associated bug is fixed
 bug_966263.in * * * skia
 
diff --git a/testing/resources/pixel/bug_1355_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1355_expected_skia.pdf.0.png
index 5974c6b..a44a9a1 100644
--- a/testing/resources/pixel/bug_1355_expected_skia.pdf.0.png
+++ b/testing/resources/pixel/bug_1355_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1355_expected_skiapaths.pdf.0.png b/testing/resources/pixel/bug_1355_expected_skiapaths.pdf.0.png
new file mode 100644
index 0000000..6bb03ec
--- /dev/null
+++ b/testing/resources/pixel/bug_1355_expected_skiapaths.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1402_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1402_expected_skia.pdf.0.png
index ef8d744..a0f05ff 100644
--- a/testing/resources/pixel/bug_1402_expected_skia.pdf.0.png
+++ b/testing/resources/pixel/bug_1402_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1402_expected_skiapaths.pdf.0.png b/testing/resources/pixel/bug_1402_expected_skiapaths.pdf.0.png
new file mode 100644
index 0000000..38ea7c4
--- /dev/null
+++ b/testing/resources/pixel/bug_1402_expected_skiapaths.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1752_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1752_expected_skia.pdf.0.png
index 6c129ef..d5aadb9 100644
--- a/testing/resources/pixel/bug_1752_expected_skia.pdf.0.png
+++ b/testing/resources/pixel/bug_1752_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/text_form_custom_font_expected_skia.pdf.0.png b/testing/resources/pixel/text_form_custom_font_expected_skia.pdf.0.png
index 5f898f8..47582b6 100644
--- a/testing/resources/pixel/text_form_custom_font_expected_skia.pdf.0.png
+++ b/testing/resources/pixel/text_form_custom_font_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/text_form_custom_font_expected_skiapaths.pdf.0.png b/testing/resources/pixel/text_form_custom_font_expected_skiapaths.pdf.0.png
new file mode 100644
index 0000000..b0554ff
--- /dev/null
+++ b/testing/resources/pixel/text_form_custom_font_expected_skiapaths.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/static_list_box_caption_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/static_list_box_caption_expected_skia.pdf.0.png
index a2c47a3..3beefe0 100644
--- a/testing/resources/pixel/xfa_specific/static_list_box_caption_expected_skia.pdf.0.png
+++ b/testing/resources/pixel/xfa_specific/static_list_box_caption_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skia.pdf.0.png
index 210ee7f..2585092 100644
--- a/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skia.pdf.0.png
+++ b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skia.pdf.1.png b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skia.pdf.1.png
index b384034..30d0e01 100644
--- a/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skia.pdf.1.png
+++ b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skia.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skiapaths.pdf.0.png b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skiapaths.pdf.0.png
new file mode 100644
index 0000000..993ebaa
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skiapaths.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skiapaths.pdf.1.png b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skiapaths.pdf.1.png
new file mode 100644
index 0000000..f621be2
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skiapaths.pdf.1.png
Binary files differ