Rewrite and rename CPDF_Font::TT2PDF()

Change the value parameter for TT2PDF() from FT_Pos to int64_t, so it
does not depend on FreeType. Change the other parameter from CFX_Face to
the font's units per EM value. Also give the function a more descriptive
name. Then update all the callers accordingly.

Change-Id: Id3e8b828831025c0f5740947dc128222e07d0ca4
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/115770
Reviewed-by: Dominik Röttsches <drott@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/font/cpdf_font.cpp b/core/fpdfapi/font/cpdf_font.cpp
index e87aa36..6726cf8 100644
--- a/core/fpdfapi/font/cpdf_font.cpp
+++ b/core/fpdfapi/font/cpdf_font.cpp
@@ -222,12 +222,13 @@
     if (face) {
       // Note that `m_FontBBox` is deliberately flipped.
       const FX_RECT raw_bbox = face->GetBBox();
-      m_FontBBox.left = TT2PDF(raw_bbox.left, face);
-      m_FontBBox.bottom = TT2PDF(raw_bbox.top, face);
-      m_FontBBox.right = TT2PDF(raw_bbox.right, face);
-      m_FontBBox.top = TT2PDF(raw_bbox.bottom, face);
-      m_Ascent = TT2PDF(face->GetAscender(), face);
-      m_Descent = TT2PDF(face->GetDescender(), face);
+      const uint16_t upem = face->GetUnitsPerEm();
+      m_FontBBox.left = NormalizeFontMetric(raw_bbox.left, upem);
+      m_FontBBox.bottom = NormalizeFontMetric(raw_bbox.top, upem);
+      m_FontBBox.right = NormalizeFontMetric(raw_bbox.right, upem);
+      m_FontBBox.top = NormalizeFontMetric(raw_bbox.bottom, upem);
+      m_Ascent = NormalizeFontMetric(face->GetAscender(), upem);
+      m_Descent = NormalizeFontMetric(face->GetDescender(), upem);
     } else {
       bool bFirst = true;
       for (int i = 0; i < 256; i++) {
@@ -407,13 +408,13 @@
 }
 
 // static
-int CPDF_Font::TT2PDF(FT_Pos m, const RetainPtr<CFX_Face>& face) {
-  int upm = face->GetUnitsPerEm();
-  if (upm == 0)
-    return pdfium::base::saturated_cast<int>(m);
+int CPDF_Font::NormalizeFontMetric(int64_t value, uint16_t upem) {
+  if (upem == 0) {
+    return pdfium::base::saturated_cast<int>(value);
+  }
 
-  const double dm = (m * 1000.0 + upm / 2) / upm;
-  return pdfium::base::saturated_cast<int>(dm);
+  const double scaled_value = (value * 1000.0 + upem / 2) / upem;
+  return pdfium::base::saturated_cast<int>(scaled_value);
 }
 
 // static
@@ -421,9 +422,11 @@
   FXFT_FaceRec* rec = face->GetRec();
   pdfium::base::ClampedNumeric<FT_Pos> left = FXFT_Get_Glyph_HoriBearingX(rec);
   pdfium::base::ClampedNumeric<FT_Pos> top = FXFT_Get_Glyph_HoriBearingY(rec);
-  return FX_RECT(TT2PDF(left, face), TT2PDF(top, face),
-                 TT2PDF(left + FXFT_Get_Glyph_Width(rec), face),
-                 TT2PDF(top - FXFT_Get_Glyph_Height(rec), face));
+  const uint16_t upem = face->GetUnitsPerEm();
+  return FX_RECT(NormalizeFontMetric(left, upem),
+                 NormalizeFontMetric(top, upem),
+                 NormalizeFontMetric(left + FXFT_Get_Glyph_Width(rec), upem),
+                 NormalizeFontMetric(top - FXFT_Get_Glyph_Height(rec), upem));
 }
 
 // static
diff --git a/core/fpdfapi/font/cpdf_font.h b/core/fpdfapi/font/cpdf_font.h
index e2f9cf3..7c733eb 100644
--- a/core/fpdfapi/font/cpdf_font.h
+++ b/core/fpdfapi/font/cpdf_font.h
@@ -139,7 +139,11 @@
   CPDF_Font(CPDF_Document* pDocument, RetainPtr<CPDF_Dictionary> pFontDict);
   ~CPDF_Font() override;
 
-  static int TT2PDF(FT_Pos m, const RetainPtr<CFX_Face>& face);
+  // Take a font metric `value` and scale it down by the font's `upem`. If the
+  // font is not scalable, i.e. `upem` is 0, then return `value` as is.
+  // If the computed result is excessively large and does not fit in an int,
+  // NormalizeFontMetric() handles that with `saturated_cast()`.
+  static int NormalizeFontMetric(int64_t value, uint16_t upem);
   static FX_RECT GetCharBBoxForFace(const RetainPtr<CFX_Face>& face);
 
   // Commonly used wrappers for UseTTCharmap().
diff --git a/core/fpdfapi/font/cpdf_simplefont.cpp b/core/fpdfapi/font/cpdf_simplefont.cpp
index eecdf5a..b411257 100644
--- a/core/fpdfapi/font/cpdf_simplefont.cpp
+++ b/core/fpdfapi/font/cpdf_simplefont.cpp
@@ -91,7 +91,8 @@
   m_CharBBox[charcode] = GetCharBBoxForFace(face);
 
   if (m_bUseFontWidth) {
-    int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(face_rec), face);
+    int TT_Width = NormalizeFontMetric(FXFT_Get_Glyph_HoriAdvance(face_rec),
+                                       face->GetUnitsPerEm());
     if (m_CharWidth[charcode] == 0xffff) {
       m_CharWidth[charcode] = TT_Width;
     } else if (TT_Width && !IsEmbedded()) {