Decouple anti-alias setting from FT_Render_Mode

This CL decouples the anti-alias setting from the previous freetype
callers. This is done by introducing a new enum, AARenderMode, and a
function GetFTRenderMode(), which is used to abstract the antialiasing
setting.

This change is part of the ongoing effort to encapsulate FreeType usage,
which makes future adjustments to anti-aliasing logic easier and
cleaner.

Change-Id: I6ef3d17ca6af94972e48691311df088f5cb6f64d
Bug: 452087737
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/138530
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index c3103d5..1242da1 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -1089,7 +1089,7 @@
     return true;
   }
 
-  FX_RECT rect = GetGlyphsBBox(glyphs, 0);
+  FX_RECT rect = GetGlyphsBBox(glyphs, FontAntiAliasingMode::kNormal);
   auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
   if (!bitmap->Create(rect.Width(), rect.Height(), FXDIB_Format::k8bppMask)) {
     return true;
diff --git a/core/fxge/apple/fx_apple_impl.cpp b/core/fxge/apple/fx_apple_impl.cpp
index ef176e3..0cb5226 100644
--- a/core/fxge/apple/fx_apple_impl.cpp
+++ b/core/fxge/apple/fx_apple_impl.cpp
@@ -22,6 +22,7 @@
 #include "core/fxge/cfx_renderdevice.h"
 #include "core/fxge/cfx_substfont.h"
 #include "core/fxge/dib/cfx_dibitmap.h"
+#include "core/fxge/fx_font.h"
 #include "core/fxge/text_char_pos.h"
 
 namespace {
@@ -181,7 +182,7 @@
     uint32_t glyph_index,
     const CFX_Matrix& matrix,
     int dest_width,
-    int anti_alias) {
+    FontAntiAliasingMode anti_alias) {
   return nullptr;
 }
 
diff --git a/core/fxge/cfx_face.cpp b/core/fxge/cfx_face.cpp
index 3fe1029..42e87e5 100644
--- a/core/fxge/cfx_face.cpp
+++ b/core/fxge/cfx_face.cpp
@@ -530,12 +530,13 @@
   return pdfium::checked_cast<int>(GetRec()->num_glyphs);
 }
 
-std::unique_ptr<CFX_GlyphBitmap> CFX_Face::RenderGlyph(const CFX_Font* font,
-                                                       uint32_t glyph_index,
-                                                       bool bFontStyle,
-                                                       const CFX_Matrix& matrix,
-                                                       int dest_width,
-                                                       int anti_alias) {
+std::unique_ptr<CFX_GlyphBitmap> CFX_Face::RenderGlyph(
+    const CFX_Font* font,
+    uint32_t glyph_index,
+    bool bFontStyle,
+    const CFX_Matrix& matrix,
+    int dest_width,
+    FontAntiAliasingMode anti_alias) {
   FT_Matrix ft_matrix;
   ft_matrix.xx = matrix.a / 64 * 65536;
   ft_matrix.xy = matrix.c / 64 * 65536;
@@ -621,7 +622,7 @@
   int dib_width = bitmap.width;
   auto pGlyphBitmap =
       std::make_unique<CFX_GlyphBitmap>(glyph->bitmap_left, glyph->bitmap_top);
-  const FXDIB_Format format = anti_alias == FT_RENDER_MODE_MONO
+  const FXDIB_Format format = anti_alias == FontAntiAliasingMode::kMono
                                   ? FXDIB_Format::k1bppMask
                                   : FXDIB_Format::k8bppMask;
   if (!pGlyphBitmap->GetBitmap()->Create(dib_width, bitmap.rows, format)) {
@@ -632,9 +633,9 @@
   uint8_t* pDestBuf = pGlyphBitmap->GetBitmap()->GetWritableBuffer().data();
   const uint8_t* pSrcBuf = bitmap.buffer;
   UNSAFE_TODO({
-    if (anti_alias != FT_RENDER_MODE_MONO &&
+    if (anti_alias != FontAntiAliasingMode::kMono &&
         bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
-      unsigned int bytes = anti_alias == FT_RENDER_MODE_LCD ? 3 : 1;
+      unsigned int bytes = anti_alias == FontAntiAliasingMode::kLcd ? 3 : 1;
       for (unsigned int i = 0; i < bitmap.rows; i++) {
         for (unsigned int n = 0; n < bitmap.width; n++) {
           uint8_t data =
diff --git a/core/fxge/cfx_face.h b/core/fxge/cfx_face.h
index 0753aff..048cf14 100644
--- a/core/fxge/cfx_face.h
+++ b/core/fxge/cfx_face.h
@@ -20,6 +20,7 @@
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/span.h"
 #include "core/fxge/freetype/fx_freetype.h"
+#include "core/fxge/fx_font.h"
 
 namespace fxge {
 enum class FontEncoding : uint32_t;
@@ -115,7 +116,7 @@
                                                bool bFontStyle,
                                                const CFX_Matrix& matrix,
                                                int dest_width,
-                                               int anti_alias);
+                                               FontAntiAliasingMode anti_alias);
   std::unique_ptr<CFX_Path> LoadGlyphPath(uint32_t glyph_index,
                                           int dest_width,
                                           bool is_vertical,
diff --git a/core/fxge/cfx_font.cpp b/core/fxge/cfx_font.cpp
index 915e2e1..f760ec4 100644
--- a/core/fxge/cfx_font.cpp
+++ b/core/fxge/cfx_font.cpp
@@ -386,7 +386,7 @@
     bool bFontStyle,
     const CFX_Matrix& matrix,
     int dest_width,
-    int anti_alias,
+    FontAntiAliasingMode anti_alias,
     CFX_TextRenderOptions* text_options) const {
   return GetOrCreateGlyphCache()->LoadGlyphBitmap(this, glyph_index, bFontStyle,
                                                   matrix, dest_width,
diff --git a/core/fxge/cfx_font.h b/core/fxge/cfx_font.h
index ff4bee1..919ee7c 100644
--- a/core/fxge/cfx_font.h
+++ b/core/fxge/cfx_font.h
@@ -22,10 +22,7 @@
 #include "core/fxcrt/span.h"
 #include "core/fxcrt/unowned_ptr_exclusion.h"
 #include "core/fxge/cfx_face.h"
-
-#if defined(PDF_USE_SKIA)
 #include "core/fxge/fx_font.h"
-#endif
 
 class CFX_GlyphBitmap;
 class CFX_GlyphCache;
@@ -91,7 +88,7 @@
       bool bFontStyle,
       const CFX_Matrix& matrix,
       int dest_width,
-      int anti_alias,
+      FontAntiAliasingMode 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) const;
diff --git a/core/fxge/cfx_glyphcache.cpp b/core/fxge/cfx_glyphcache.cpp
index 7954089..0dafc22 100644
--- a/core/fxge/cfx_glyphcache.cpp
+++ b/core/fxge/cfx_glyphcache.cpp
@@ -19,6 +19,7 @@
 #include "core/fxge/cfx_glyphbitmap.h"
 #include "core/fxge/cfx_path.h"
 #include "core/fxge/cfx_substfont.h"
+#include "core/fxge/fx_font.h"
 
 #if defined(PDF_USE_SKIA)
 #include "third_party/skia/include/core/SkFontMgr.h"         // nogncheck
@@ -47,7 +48,7 @@
   UniqueKeyGen(const CFX_Font* font,
                const CFX_Matrix& matrix,
                int dest_width,
-               int anti_alias,
+               FontAntiAliasingMode anti_alias,
                bool bNative);
 
   pdfium::span<const uint8_t> span() const;
@@ -75,7 +76,7 @@
 UniqueKeyGen::UniqueKeyGen(const CFX_Font* font,
                            const CFX_Matrix& matrix,
                            int dest_width,
-                           int anti_alias,
+                           FontAntiAliasingMode anti_alias,
                            bool bNative) {
   int nMatrixA = static_cast<int>(matrix.a * 10000);
   int nMatrixB = static_cast<int>(matrix.b * 10000);
@@ -86,11 +87,11 @@
   if (bNative) {
     if (font->GetSubstFont()) {
       Initialize({nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width,
-                  anti_alias, font->GetSubstFont()->weight_,
+                  static_cast<int>(anti_alias), font->GetSubstFont()->weight_,
                   font->GetSubstFont()->italic_angle_, font->IsVertical(), 3});
     } else {
-      Initialize(
-          {nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width, anti_alias, 3});
+      Initialize({nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width,
+                  static_cast<int>(anti_alias), 3});
     }
     return;
   }
@@ -98,12 +99,12 @@
 
   CHECK(!bNative);
   if (font->GetSubstFont()) {
-    Initialize({nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width, anti_alias,
-                font->GetSubstFont()->weight_,
+    Initialize({nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width,
+                static_cast<int>(anti_alias), font->GetSubstFont()->weight_,
                 font->GetSubstFont()->italic_angle_, font->IsVertical()});
   } else {
-    Initialize(
-        {nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width, anti_alias});
+    Initialize({nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width,
+                static_cast<int>(anti_alias)});
   }
 }
 
@@ -120,7 +121,7 @@
     bool bFontStyle,
     const CFX_Matrix& matrix,
     int dest_width,
-    int anti_alias) {
+    FontAntiAliasingMode anti_alias) {
   if (!face_) {
     return nullptr;
   }
@@ -157,7 +158,7 @@
     bool bFontStyle,
     const CFX_Matrix& matrix,
     int dest_width,
-    int anti_alias,
+    FontAntiAliasingMode anti_alias,
     CFX_TextRenderOptions* text_options) {
   if (glyph_index == kInvalidGlyphIndex) {
     return nullptr;
@@ -306,7 +307,7 @@
     uint32_t glyph_index,
     bool bFontStyle,
     int dest_width,
-    int anti_alias) {
+    FontAntiAliasingMode anti_alias) {
   SizeGlyphCache* pSizeCache;
   auto it = size_map_.find(FaceGlyphsKey);
   if (it == size_map_.end()) {
diff --git a/core/fxge/cfx_glyphcache.h b/core/fxge/cfx_glyphcache.h
index 03c971f..d319379 100644
--- a/core/fxge/cfx_glyphcache.h
+++ b/core/fxge/cfx_glyphcache.h
@@ -15,9 +15,9 @@
 #include "core/fxcrt/observed_ptr.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxge/cfx_face.h"
+#include "core/fxge/fx_font.h"
 
 #if defined(PDF_USE_SKIA)
-#include "core/fxge/fx_font.h"
 #include "third_party/skia/include/core/SkRefCnt.h"  // nogncheck
 #endif
 
@@ -36,7 +36,7 @@
                                          bool bFontStyle,
                                          const CFX_Matrix& matrix,
                                          int dest_width,
-                                         int anti_alias,
+                                         FontAntiAliasingMode anti_alias,
                                          CFX_TextRenderOptions* text_options);
   const CFX_Path* LoadGlyphPath(const CFX_Font* font,
                                 uint32_t glyph_index,
@@ -69,20 +69,20 @@
                                                bool bFontStyle,
                                                const CFX_Matrix& matrix,
                                                int dest_width,
-                                               int anti_alias);
+                                               FontAntiAliasingMode anti_alias);
   std::unique_ptr<CFX_GlyphBitmap> RenderGlyph_Nativetext(
       const CFX_Font* font,
       uint32_t glyph_index,
       const CFX_Matrix& matrix,
       int dest_width,
-      int anti_alias);
+      FontAntiAliasingMode anti_alias);
   CFX_GlyphBitmap* LookUpGlyphBitmap(const CFX_Font* font,
                                      const CFX_Matrix& matrix,
                                      const ByteString& FaceGlyphsKey,
                                      uint32_t glyph_index,
                                      bool bFontStyle,
                                      int dest_width,
-                                     int anti_alias);
+                                     FontAntiAliasingMode anti_alias);
   RetainPtr<CFX_Face> const face_;
   std::map<ByteString, SizeGlyphCache> size_map_;
   std::map<PathMapKey, std::unique_ptr<CFX_Path>> path_map_;
diff --git a/core/fxge/cfx_renderdevice.cpp b/core/fxge/cfx_renderdevice.cpp
index d39c95d..7c530ba 100644
--- a/core/fxge/cfx_renderdevice.cpp
+++ b/core/fxge/cfx_renderdevice.cpp
@@ -505,6 +505,12 @@
   return CFX_DIBBase::kPlatformRGBFormat;
 }
 
+bool IsModeNonLCD(FontAntiAliasingMode mode) {
+  return mode == FontAntiAliasingMode::kNormal ||
+         mode == FontAntiAliasingMode::kLight ||
+         mode == FontAntiAliasingMode::kMono;
+}
+
 }  // namespace
 
 CFX_RenderDevice::CFX_RenderDevice() = default;
@@ -1086,7 +1092,7 @@
                                       uint32_t fill_color,
                                       const CFX_TextRenderOptions& options) {
   // `anti_alias` and `normalize` don't affect Skia rendering.
-  int anti_alias = FT_RENDER_MODE_MONO;
+  FontAntiAliasingMode anti_alias = FontAntiAliasingMode::kMono;
   bool normalize = false;
   const bool is_text_smooth = options.IsSmooth();
   // |text_options| has the potential to affect all derived classes of
@@ -1100,7 +1106,7 @@
         // 6225973, 6243070, 6393145, 6421054, 6282327, and 6624828; the latest
         // one expires 10/7/19.  This makes LCD anti-aliasing very ugly, so we
         // instead fall back on NORMAL anti-aliasing.
-        anti_alias = FT_RENDER_MODE_NORMAL;
+        anti_alias = FontAntiAliasingMode::kNormal;
         if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
           // Since |anti_alias| doesn't affect Skia rendering, and Skia only
           // follows strictly to the options provided by |text_options|, we need
@@ -1112,16 +1118,16 @@
         // Whether Skia uses LCD optimization should strictly follow the
         // rendering options provided by |text_options|. No change needs to be
         // done for |text_options| here.
-        anti_alias = FT_RENDER_MODE_LCD;
+        anti_alias = FontAntiAliasingMode::kLcd;
         normalize = true;
       } else if (bpp_ < 16) {
         // This case doesn't apply to Skia since Skia always have |bpp_| = 32.
-        anti_alias = FT_RENDER_MODE_NORMAL;
+        anti_alias = FontAntiAliasingMode::kNormal;
       } else {
         // Whether Skia uses LCD optimization should strictly follow the
         // rendering options provided by |text_options|. No change needs to be
         // done for |text_options| here.
-        anti_alias = FT_RENDER_MODE_LCD;
+        anti_alias = FontAntiAliasingMode::kLcd;
         normalize = !font->HasFaceRec() ||
                     options.aliasing_type != CFX_TextRenderOptions::kLcd;
       }
@@ -1173,7 +1179,7 @@
   std::vector<TextGlyphPos> glyphs(pCharPos.size());
   for (auto [charpos, glyph] : fxcrt::Zip(pCharPos, pdfium::span(glyphs))) {
     glyph.device_origin_ = text2Device.Transform(charpos.origin_);
-    glyph.origin_.x = anti_alias < FT_RENDER_MODE_LCD
+    glyph.origin_.x = IsModeNonLCD(anti_alias)
                           ? FXSYS_roundf(glyph.device_origin_.x)
                           : static_cast<int>(floor(glyph.device_origin_.x));
     glyph.origin_.y = FXSYS_roundf(glyph.device_origin_.y);
@@ -1183,7 +1189,7 @@
         charpos.glyph_index_, charpos.font_style_, matrix,
         charpos.font_char_width_, anti_alias, &text_options);
   }
-  if (anti_alias < FT_RENDER_MODE_LCD && glyphs.size() > 1) {
+  if (IsModeNonLCD(anti_alias) && glyphs.size() > 1) {
     AdjustGlyphSpace(&glyphs);
   }
 
@@ -1197,7 +1203,7 @@
   int pixel_height = bmp_rect.Height();
   int pixel_left = bmp_rect.left;
   int pixel_top = bmp_rect.top;
-  if (anti_alias == FT_RENDER_MODE_MONO) {
+  if (anti_alias == FontAntiAliasingMode::kMono) {
     auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
     if (!bitmap->Create(pixel_width, pixel_height, FXDIB_Format::k1bppMask)) {
       return false;
@@ -1242,7 +1248,7 @@
   }
   int dest_width = pixel_width;
   FX_BGRA_STRUCT<uint8_t> bgra;
-  if (anti_alias == FT_RENDER_MODE_LCD) {
+  if (anti_alias == FontAntiAliasingMode::kLcd) {
     bgra = ArgbToBGRAStruct(fill_color);
   }
 
@@ -1259,7 +1265,7 @@
     const RetainPtr<CFX_DIBitmap>& pGlyph = glyph.glyph_->GetBitmap();
     int ncols = pGlyph->GetWidth();
     int nrows = pGlyph->GetHeight();
-    if (anti_alias == FT_RENDER_MODE_NORMAL) {
+    if (anti_alias == FontAntiAliasingMode::kNormal) {
       if (!bitmap->CompositeMask(point.value().x, point.value().y, ncols, nrows,
                                  pGlyph, fill_color, 0, 0, BlendMode::kNormal,
                                  nullptr, false)) {
diff --git a/core/fxge/fx_font.cpp b/core/fxge/fx_font.cpp
index e5d15a4..1877d90 100644
--- a/core/fxge/fx_font.cpp
+++ b/core/fxge/fx_font.cpp
@@ -35,7 +35,8 @@
 
 }  // namespace
 
-FX_RECT GetGlyphsBBox(const std::vector<TextGlyphPos>& glyphs, int anti_alias) {
+FX_RECT GetGlyphsBBox(const std::vector<TextGlyphPos>& glyphs,
+                      FontAntiAliasingMode anti_alias) {
   FX_RECT rect;
   bool bStarted = false;
   for (const TextGlyphPos& glyph : glyphs) {
@@ -49,7 +50,7 @@
     }
 
     int char_width = glyph.glyph_->GetBitmap()->GetWidth();
-    if (anti_alias == FT_RENDER_MODE_LCD) {
+    if (anti_alias == FontAntiAliasingMode::kLcd) {
       char_width /= 3;
     }
 
diff --git a/core/fxge/fx_font.h b/core/fxge/fx_font.h
index 4891c26..dcf11d1 100644
--- a/core/fxge/fx_font.h
+++ b/core/fxge/fx_font.h
@@ -49,6 +49,16 @@
 
 }  // namespace pdfium
 
+enum class FontAntiAliasingMode : int {
+  kNormal,
+  kLight,
+  kMono,
+  kLcd,
+  kLcdV,
+  kSdf,
+  kMax
+};
+
 /* Other font flags */
 #define FXFONT_USEEXTERNATTR 0x80000
 
@@ -65,7 +75,8 @@
 
 class TextGlyphPos;
 
-FX_RECT GetGlyphsBBox(const std::vector<TextGlyphPos>& glyphs, int anti_alias);
+FX_RECT GetGlyphsBBox(const std::vector<TextGlyphPos>& glyphs,
+                      FontAntiAliasingMode anti_alias);
 
 ByteString GetNameFromTT(pdfium::span<const uint8_t> name_table, uint32_t name);
 size_t GetTTCIndex(pdfium::span<const uint8_t> font_data, size_t font_offset);