Abstract some raw data tables in CFX_Font.

Provide methods to process the data and give the callers what they
really want. Adjust the raw data to do more pre-computation.

Change-Id: I278c82ab4e2f4a44a97feca512fe2c2350c8b7ed
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/73071
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxge/cfx_font.cpp b/core/fxge/cfx_font.cpp
index 35e136d..2de7eb8 100644
--- a/core/fxge/cfx_font.cpp
+++ b/core/fxge/cfx_font.cpp
@@ -24,6 +24,7 @@
 #include "core/fxge/fx_font.h"
 #include "core/fxge/scoped_font_transform.h"
 #include "third_party/base/span.h"
+#include "third_party/base/stl_util.h"
 
 #define EM_ADJUST(em, a) (em == 0 ? (a) : (a)*1000 / em)
 
@@ -180,23 +181,22 @@
   return !style.IsEmpty() && style != "Regular";
 }
 
-}  // namespace
-
-const char CFX_Font::s_AngleSkew[] = {
-    0,  2,  3,  5,  7,  9,  11, 12, 14, 16, 18, 19, 21, 23, 25,
-    27, 29, 31, 32, 34, 36, 38, 40, 42, 45, 47, 49, 51, 53, 55,
+constexpr int8_t kAngleSkew[] = {
+    -0,  -2,  -3,  -5,  -7,  -9,  -11, -12, -14, -16, -18, -19, -21, -23, -25,
+    -27, -29, -31, -32, -34, -36, -38, -40, -42, -45, -47, -49, -51, -53, -55,
 };
 
-const uint8_t CFX_Font::s_WeightPow[] = {
-    0,  3,  6,  7,  8,  9,  11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22,
-    23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 36, 36, 37,
-    37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42,
-    42, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47,
-    47, 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 50,
-    51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53,
+constexpr uint8_t kWeightPow[] = {
+    0,   6,   12,  14,  16,  18,  22,  24,  28,  30,  32,  34,  36,  38,  40,
+    42,  44,  46,  48,  50,  52,  54,  56,  58,  60,  62,  64,  66,  68,  70,
+    70,  72,  72,  74,  74,  74,  76,  76,  76,  78,  78,  78,  80,  80,  80,
+    82,  82,  82,  84,  84,  84,  84,  86,  86,  86,  88,  88,  88,  88,  90,
+    90,  90,  90,  92,  92,  92,  92,  94,  94,  94,  94,  96,  96,  96,  96,
+    96,  98,  98,  98,  98,  100, 100, 100, 100, 100, 102, 102, 102, 102, 102,
+    104, 104, 104, 104, 104, 106, 106, 106, 106, 106,
 };
 
-const uint8_t CFX_Font::s_WeightPow_11[] = {
+constexpr uint8_t kWeightPow11[] = {
     0,  4,  7,  8,  9,  10, 12, 13, 15, 17, 18, 19, 20, 21, 22, 23, 24,
     25, 26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 39, 40, 40, 41,
     41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46,
@@ -205,15 +205,24 @@
     56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58,
 };
 
-const uint8_t CFX_Font::s_WeightPow_SHIFTJIS[] = {
-    0,  0,  1,  2,  3,  4,  5,  7,  8,  10, 11, 13, 14, 16, 17, 19, 21,
-    22, 24, 26, 28, 30, 32, 33, 35, 37, 39, 41, 43, 45, 48, 48, 48, 48,
-    49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53,
-    53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56,
-    56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 58,
-    59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60,
+constexpr uint8_t kWeightPowShiftJis[] = {
+    0,   0,   2,   4,   6,   8,   10,  14,  16,  20,  22,  26,  28,  32,  34,
+    38,  42,  44,  48,  52,  56,  60,  64,  66,  70,  74,  78,  82,  86,  90,
+    96,  96,  96,  96,  98,  98,  98,  100, 100, 100, 100, 102, 102, 102, 102,
+    104, 104, 104, 104, 104, 106, 106, 106, 106, 106, 108, 108, 108, 108, 108,
+    110, 110, 110, 110, 110, 112, 112, 112, 112, 112, 112, 114, 114, 114, 114,
+    114, 114, 114, 116, 116, 116, 116, 116, 116, 116, 118, 118, 118, 118, 118,
+    118, 118, 120, 120, 120, 120, 120, 120, 120, 120,
 };
 
+constexpr size_t kWeightPowArraySize = 100;
+static_assert(kWeightPowArraySize == pdfium::size(kWeightPow), "Wrong size");
+static_assert(kWeightPowArraySize == pdfium::size(kWeightPow11), "Wrong size");
+static_assert(kWeightPowArraySize == pdfium::size(kWeightPowShiftJis),
+              "Wrong size");
+
+}  // namespace
+
 const CFX_Font::CharsetFontMap CFX_Font::defaultTTFMap[] = {
     {FX_CHARSET_ANSI, kDefaultAnsiFontName},
     {FX_CHARSET_ChineseSimplified, "SimSun"},
@@ -649,15 +658,7 @@
   FT_Matrix ft_matrix = {65536, 0, 0, 65536};
   if (m_pSubstFont) {
     if (m_pSubstFont->m_ItalicAngle) {
-      int skew = m_pSubstFont->m_ItalicAngle;
-      // |skew| is nonpositive so |-skew| is used as the index. We need to make
-      // sure |skew| != INT_MIN since -INT_MIN is undefined.
-      if (skew <= 0 && skew != std::numeric_limits<int>::min() &&
-          static_cast<size_t>(-skew) < kAngleSkewArraySize) {
-        skew = -s_AngleSkew[-skew];
-      } else {
-        skew = -58;
-      }
+      int skew = GetSkewFromAngle(m_pSubstFont->m_ItalicAngle);
       if (m_bVertical)
         ft_matrix.yx += ft_matrix.yy * skew / 100;
       else
@@ -675,13 +676,13 @@
     return nullptr;
   if (m_pSubstFont && !m_pSubstFont->m_bFlagMM &&
       m_pSubstFont->m_Weight > 400) {
-    uint32_t index = (m_pSubstFont->m_Weight - 400) / 10;
-    index = std::min(index, static_cast<uint32_t>(kWeightPowArraySize - 1));
-    int level = 0;
+    uint32_t index = std::min<uint32_t>((m_pSubstFont->m_Weight - 400) / 10,
+                                        kWeightPowArraySize - 1);
+    int level;
     if (m_pSubstFont->m_Charset == FX_CHARSET_ShiftJIS)
-      level = s_WeightPow_SHIFTJIS[index] * 2 * 65536 / 36655;
+      level = kWeightPowShiftJis[index] * 65536 / 36655;
     else
-      level = s_WeightPow[index] * 2;
+      level = kWeightPow[index];
     FT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face->GetRec()), level);
   }
 
@@ -727,6 +728,27 @@
   return GetOrCreateGlyphCache()->LoadGlyphPath(this, glyph_index, dest_width);
 }
 
+// static
+int CFX_Font::GetWeightLevel(int charset, size_t index) {
+  if (index >= kWeightPowArraySize)
+    return -1;
+
+  if (charset == FX_CHARSET_ShiftJIS)
+    return kWeightPowShiftJis[index];
+  return kWeightPow11[index];
+}
+
+// static
+int CFX_Font::GetSkewFromAngle(int angle) {
+  // |angle| is non-positive so |-angle| is used as the index. Need to make sure
+  // |angle| != INT_MIN since -INT_MIN is undefined.
+  if (angle > 0 || angle == std::numeric_limits<int>::min() ||
+      static_cast<size_t>(-angle) >= pdfium::size(kAngleSkew)) {
+    return -58;
+  }
+  return kAngleSkew[-angle];
+}
+
 #if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
 CFX_TypeFace* CFX_Font::GetDeviceCache() const {
   return GetOrCreateGlyphCache()->GetDeviceCache(this);
diff --git a/core/fxge/cfx_font.h b/core/fxge/cfx_font.h
index 64fdbb7..ea9e353 100644
--- a/core/fxge/cfx_font.h
+++ b/core/fxge/cfx_font.h
@@ -112,12 +112,11 @@
   void SetPlatformFont(void* font) { m_pPlatformFont = font; }
 #endif
 
-  static constexpr size_t kAngleSkewArraySize = 30;
-  static const char s_AngleSkew[kAngleSkewArraySize];
-  static constexpr size_t kWeightPowArraySize = 100;
-  static const uint8_t s_WeightPow[kWeightPowArraySize];
-  static const uint8_t s_WeightPow_11[kWeightPowArraySize];
-  static const uint8_t s_WeightPow_SHIFTJIS[kWeightPowArraySize];
+  // Returns negative values on failure.
+  static int GetWeightLevel(int charset, size_t index);
+
+  // |angle| is typically negative.
+  static int GetSkewFromAngle(int angle);
 
   // This struct should be the same as FPDF_CharsetFontMap.
   struct CharsetFontMap {
diff --git a/core/fxge/cfx_glyphcache.cpp b/core/fxge/cfx_glyphcache.cpp
index 928f28e..f51beea 100644
--- a/core/fxge/cfx_glyphcache.cpp
+++ b/core/fxge/cfx_glyphcache.cpp
@@ -121,20 +121,13 @@
   const CFX_SubstFont* pSubstFont = pFont->GetSubstFont();
   if (pSubstFont) {
     bUseCJKSubFont = pSubstFont->m_bSubstCJK && bFontStyle;
-    int skew = 0;
+    int angle;
     if (bUseCJKSubFont)
-      skew = pSubstFont->m_bItalicCJK ? -15 : 0;
+      angle = pSubstFont->m_bItalicCJK ? -15 : 0;
     else
-      skew = pSubstFont->m_ItalicAngle;
-    if (skew) {
-      // |skew| is nonpositive so |-skew| is used as the index. We need to make
-      // sure |skew| != INT_MIN since -INT_MIN is undefined.
-      if (skew <= 0 && skew != std::numeric_limits<int>::min() &&
-          static_cast<size_t>(-skew) < CFX_Font::kAngleSkewArraySize) {
-        skew = -CFX_Font::s_AngleSkew[-skew];
-      } else {
-        skew = -58;
-      }
+      angle = pSubstFont->m_ItalicAngle;
+    if (angle) {
+      int skew = CFX_Font::GetSkewFromAngle(angle);
       if (pFont->IsVertical())
         ft_matrix.yx += ft_matrix.yy * skew / 100;
       else
@@ -170,13 +163,10 @@
     weight = pSubstFont ? pSubstFont->m_Weight : 0;
   if (pSubstFont && !pSubstFont->m_bFlagMM && weight > 400) {
     uint32_t index = (weight - 400) / 10;
-    if (index >= CFX_Font::kWeightPowArraySize)
+    pdfium::base::CheckedNumeric<signed long> level =
+        CFX_Font::GetWeightLevel(pSubstFont->m_Charset, index);
+    if (level.ValueOrDefault(-1) < 0)
       return nullptr;
-    pdfium::base::CheckedNumeric<signed long> level = 0;
-    if (pSubstFont->m_Charset == FX_CHARSET_ShiftJIS)
-      level = CFX_Font::s_WeightPow_SHIFTJIS[index] * 2;
-    else
-      level = CFX_Font::s_WeightPow_11[index];
 
     level = level *
             (abs(static_cast<int>(ft_matrix.xx)) +