Enable -Wshorten-64-to-32 for core/fpdfapi/font

This is slightly complicated by the fact that many routines are
actually returning FT_Pos types, which are long, and might truncate
when assigned to other integral types. We use these where reasonable.

-- fix (pre-existing) IWYU in cpdf_font.h
-- use saturated_cast<> for simplicity
-- add helper function for FT_Pos conversion

Change-Id: I36335716fb501e90b5bb9a09b10198f71f70ab00
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/89690
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/font/BUILD.gn b/core/fpdfapi/font/BUILD.gn
index 7d8317f..a5fe8cd 100644
--- a/core/fpdfapi/font/BUILD.gn
+++ b/core/fpdfapi/font/BUILD.gn
@@ -40,6 +40,7 @@
     "cpdf_type3font.cpp",
     "cpdf_type3font.h",
   ]
+  cflags = []
   configs += [ "../../../:pdfium_strict_config" ]
   deps = [
     "../../fxcrt",
@@ -47,10 +48,13 @@
     "../cmaps",
     "../parser",
   ]
+  visibility = [ "../../../*" ]
   if (is_mac) {
     frameworks = [ "CoreFoundation.framework" ]
   }
-  visibility = [ "../../../*" ]
+  if (is_clang) {
+    cflags += [ "-Wshorten-64-to-32" ]
+  }
 }
 
 pdfium_unittest_source_set("unittests") {
diff --git a/core/fpdfapi/font/cpdf_cidfont.cpp b/core/fpdfapi/font/cpdf_cidfont.cpp
index 8981824..d841b51 100644
--- a/core/fpdfapi/font/cpdf_cidfont.cpp
+++ b/core/fpdfapi/font/cpdf_cidfont.cpp
@@ -132,13 +132,16 @@
     {8818, 0, 129, 127, 0, 19, 114}, {8819, 0, 129, 127, 0, 218, 108},
 };
 
-// Boundary values to avoid integer overflow when multiplied by 1000.
-constexpr long kMinCBox = -2147483;
-constexpr long kMaxCBox = 2147483;
-
 // Boundary value to avoid integer overflow when adding 1/64th of the value.
 constexpr int kMaxRectTop = 2114445437;
 
+int FTPosToCBoxInt(FT_Pos pos) {
+  // Boundary values to avoid integer overflow when multiplied by 1000.
+  constexpr FT_Pos kMinCBox = -2147483;
+  constexpr FT_Pos kMaxCBox = 2147483;
+  return static_cast<int>(pdfium::clamp(pos, kMinCBox, kMaxCBox));
+}
+
 #if !BUILDFLAG(IS_WIN)
 
 bool IsValidEmbeddedCharcodeFromUnicodeCharset(CIDSet charset) {
@@ -518,19 +521,18 @@
         if (!err) {
           FT_BBox cbox;
           FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &cbox);
-          cbox.xMin = pdfium::clamp(cbox.xMin, kMinCBox, kMaxCBox);
-          cbox.xMax = pdfium::clamp(cbox.xMax, kMinCBox, kMaxCBox);
-          cbox.yMin = pdfium::clamp(cbox.yMin, kMinCBox, kMaxCBox);
-          cbox.yMax = pdfium::clamp(cbox.yMax, kMinCBox, kMaxCBox);
-          int pixel_size_x = face->size->metrics.x_ppem;
-          int pixel_size_y = face->size->metrics.y_ppem;
+          const int xMin = FTPosToCBoxInt(cbox.xMin);
+          const int xMax = FTPosToCBoxInt(cbox.xMax);
+          const int yMin = FTPosToCBoxInt(cbox.yMin);
+          const int yMax = FTPosToCBoxInt(cbox.yMax);
+          const int pixel_size_x = face->size->metrics.x_ppem;
+          const int pixel_size_y = face->size->metrics.y_ppem;
           if (pixel_size_x == 0 || pixel_size_y == 0) {
-            rect = FX_RECT(cbox.xMin, cbox.yMax, cbox.xMax, cbox.yMin);
+            rect = FX_RECT(xMin, yMax, xMax, yMin);
           } else {
-            rect = FX_RECT(cbox.xMin * 1000 / pixel_size_x,
-                           cbox.yMax * 1000 / pixel_size_y,
-                           cbox.xMax * 1000 / pixel_size_x,
-                           cbox.yMin * 1000 / pixel_size_y);
+            rect =
+                FX_RECT(xMin * 1000 / pixel_size_x, yMax * 1000 / pixel_size_y,
+                        xMax * 1000 / pixel_size_x, yMin * 1000 / pixel_size_y);
           }
           rect.top = std::min(rect.top,
                               static_cast<int>(FXFT_Get_Face_Ascender(face)));
diff --git a/core/fpdfapi/font/cpdf_font.cpp b/core/fpdfapi/font/cpdf_font.cpp
index 77cbdcd..69db9fa 100644
--- a/core/fpdfapi/font/cpdf_font.cpp
+++ b/core/fpdfapi/font/cpdf_font.cpp
@@ -7,7 +7,6 @@
 #include "core/fpdfapi/font/cpdf_font.h"
 
 #include <algorithm>
-#include <limits>
 #include <memory>
 #include <utility>
 #include <vector>
@@ -34,6 +33,7 @@
 #include "core/fxge/fx_freetype.h"
 #include "third_party/base/check.h"
 #include "third_party/base/cxx17_backports.h"
+#include "third_party/base/numerics/safe_conversions.h"
 
 namespace {
 
@@ -402,15 +402,13 @@
 }
 
 // static
-int CPDF_Font::TT2PDF(int m, FXFT_FaceRec* face) {
+int CPDF_Font::TT2PDF(FT_Pos m, FXFT_FaceRec* face) {
   int upm = FXFT_Get_Face_UnitsPerEM(face);
   if (upm == 0)
-    return m;
+    return pdfium::base::saturated_cast<int>(m);
 
-  return static_cast<int>(
-      pdfium::clamp((m * 1000.0 + upm / 2) / upm,
-                    static_cast<double>(std::numeric_limits<int>::min()),
-                    static_cast<double>(std::numeric_limits<int>::max())));
+  const double dm = (m * 1000.0 + upm / 2) / upm;
+  return pdfium::base::saturated_cast<int>(dm);
 }
 
 // static
diff --git a/core/fpdfapi/font/cpdf_font.h b/core/fpdfapi/font/cpdf_font.h
index d92da3c..f7f9c36 100644
--- a/core/fpdfapi/font/cpdf_font.h
+++ b/core/fpdfapi/font/cpdf_font.h
@@ -21,6 +21,7 @@
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/cfx_font.h"
+#include "core/fxge/fx_freetype.h"
 
 class CFX_DIBitmap;
 class CFX_SubstFont;
@@ -129,7 +130,7 @@
  protected:
   CPDF_Font(CPDF_Document* pDocument, CPDF_Dictionary* pFontDict);
 
-  static int TT2PDF(int m, FXFT_FaceRec* face);
+  static int TT2PDF(FT_Pos m, FXFT_FaceRec* face);
   static bool FT_UseTTCharmap(FXFT_FaceRec* face,
                               int platform_id,
                               int encoding_id);
diff --git a/core/fpdfapi/font/cpdf_fontencoding.cpp b/core/fpdfapi/font/cpdf_fontencoding.cpp
index 41b6cf8..9c34e3a 100644
--- a/core/fpdfapi/font/cpdf_fontencoding.cpp
+++ b/core/fpdfapi/font/cpdf_fontencoding.cpp
@@ -1646,7 +1646,7 @@
 uint32_t PDF_FindCode(const uint16_t* pCodes, uint16_t unicode) {
   for (size_t i = 0; i < CPDF_FontEncoding::kEncodingTableSize; i++) {
     if (pCodes[i] == unicode)
-      return i;
+      return static_cast<uint32_t>(i);
   }
   return 0;
 }
@@ -1656,7 +1656,7 @@
 int CPDF_FontEncoding::CharCodeFromUnicode(wchar_t unicode) const {
   for (size_t i = 0; i < pdfium::size(m_Unicodes); i++) {
     if (m_Unicodes[i] == unicode)
-      return i;
+      return static_cast<int>(i);
   }
   return -1;
 }
diff --git a/core/fpdfapi/font/cpdf_simplefont.cpp b/core/fpdfapi/font/cpdf_simplefont.cpp
index 1593639..d0d0a6d 100644
--- a/core/fpdfapi/font/cpdf_simplefont.cpp
+++ b/core/fpdfapi/font/cpdf_simplefont.cpp
@@ -83,8 +83,8 @@
   if (err)
     return;
 
-  int iHoriBearingX = FXFT_Get_Glyph_HoriBearingX(face);
-  int iHoriBearingY = FXFT_Get_Glyph_HoriBearingY(face);
+  FT_Pos iHoriBearingX = FXFT_Get_Glyph_HoriBearingX(face);
+  FT_Pos iHoriBearingY = FXFT_Get_Glyph_HoriBearingY(face);
   m_CharBBox[charcode] =
       FX_RECT(TT2PDF(iHoriBearingX, face), TT2PDF(iHoriBearingY, face),
               TT2PDF(iHoriBearingX + FXFT_Get_Glyph_Width(face), face),
diff --git a/core/fpdfapi/font/cpdf_type1font.cpp b/core/fpdfapi/font/cpdf_type1font.cpp
index 0205b02..697ced4 100644
--- a/core/fpdfapi/font/cpdf_type1font.cpp
+++ b/core/fpdfapi/font/cpdf_type1font.cpp
@@ -267,17 +267,17 @@
 #endif  // BUILDFLAG(IS_APPLE)
   if (FontStyleIsSymbolic(m_Flags)) {
     for (size_t charcode = 0; charcode < kInternalTableSize; charcode++) {
-      const char* name =
-          GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode);
+      const char* name = GetAdobeCharName(m_BaseEncoding, m_CharNames,
+                                          static_cast<uint32_t>(charcode));
       if (name) {
         m_Encoding.SetUnicode(charcode, PDF_UnicodeFromAdobeName(name));
         m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.GetFaceRec(), name);
       } else {
-        m_GlyphIndex[charcode] =
-            FT_Get_Char_Index(m_Font.GetFaceRec(), charcode);
+        m_GlyphIndex[charcode] = FT_Get_Char_Index(
+            m_Font.GetFaceRec(), static_cast<uint32_t>(charcode));
         if (m_GlyphIndex[charcode]) {
-          wchar_t unicode =
-              FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
+          wchar_t unicode = FT_UnicodeFromCharCode(
+              PDFFONT_ENCODING_STANDARD, static_cast<uint32_t>(charcode));
           if (unicode == 0) {
             char name_glyph[kInternalTableSize] = {};
             FT_Get_Glyph_Name(m_Font.GetFaceRec(), m_GlyphIndex[charcode],
@@ -300,7 +300,8 @@
   bool bUnicode =
       FXFT_Select_Charmap(m_Font.GetFaceRec(), FT_ENCODING_UNICODE) == 0;
   for (size_t charcode = 0; charcode < kInternalTableSize; charcode++) {
-    const char* name = GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode);
+    const char* name = GetAdobeCharName(m_BaseEncoding, m_CharNames,
+                                        static_cast<uint32_t>(charcode));
     if (!name)
       continue;
 
@@ -310,9 +311,10 @@
       continue;
 
     if (strcmp(name, ".notdef") != 0 && strcmp(name, "space") != 0) {
-      m_GlyphIndex[charcode] = FT_Get_Char_Index(
-          m_Font.GetFaceRec(),
-          bUnicode ? m_Encoding.UnicodeFromCharCode(charcode) : charcode);
+      m_GlyphIndex[charcode] =
+          FT_Get_Char_Index(m_Font.GetFaceRec(),
+                            bUnicode ? m_Encoding.UnicodeFromCharCode(charcode)
+                                     : static_cast<uint32_t>(charcode));
     } else {
       m_Encoding.SetUnicode(charcode, 0x20);
       m_GlyphIndex[charcode] = 0xffff;