Add additional Fontations calls to CFX_Face.

Add checks against Fontations in GetStyleName(), GetOs2UnicodeRange(),
GetGlyphName(), and GetNameIndex().

Bug: 42271123
Change-Id: Ia9a174383cfb68f941ddc0886c6e67c2297922ef
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/148331
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxge/cfx_face.cpp b/core/fxge/cfx_face.cpp
index 88ecdff..cc8df64 100644
--- a/core/fxge/cfx_face.cpp
+++ b/core/fxge/cfx_face.cpp
@@ -458,7 +458,19 @@
 }
 
 ByteString CFX_Face::GetStyleName() const {
-  return ByteString(GetRec()->style_name);
+  ByteString ft_result(GetRec()->style_name);
+#if defined(PDF_ENABLE_SKIA_TYPEFACE_CHECKS)
+#if defined(PDF_ENABLE_FONTATIONS)
+  pdfium::span<const uint8_t> data = GetData();
+  rust::String skrifa_result = skrifa::get_style_name(
+      rust::Slice<const uint8_t>(data.data(), data.size()));
+  CHECK_EQ(ft_result.IsEmpty(), skrifa_result.empty());
+  if (!ft_result.IsEmpty() && !skrifa_result.empty()) {
+    CHECK_EQ(ft_result, ByteString(skrifa_result.c_str()));
+  }
+#endif  // defined(PDF_ENABLE_FONTATIONS)
+#endif  // defined(PDF_ENABLE_SKIA_TYPEFACE_CHECKS)
+  return ft_result;
 }
 
 FX_RECT CFX_Face::GetBBox() const {
@@ -561,13 +573,35 @@
 #if defined(PDF_ENABLE_XFA)
 std::optional<std::array<uint32_t, 4>> CFX_Face::GetOs2UnicodeRange() {
   auto* os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(GetRec(), FT_SFNT_OS2));
-  if (!os2) {
-    return std::nullopt;
+  std::optional<std::array<uint32_t, 4>> ft_result;
+  if (os2) {
+    ft_result =
+        std::array<uint32_t, 4>{static_cast<uint32_t>(os2->ulUnicodeRange1),
+                                static_cast<uint32_t>(os2->ulUnicodeRange2),
+                                static_cast<uint32_t>(os2->ulUnicodeRange3),
+                                static_cast<uint32_t>(os2->ulUnicodeRange4)};
   }
-  return std::array<uint32_t, 4>{static_cast<uint32_t>(os2->ulUnicodeRange1),
-                                 static_cast<uint32_t>(os2->ulUnicodeRange2),
-                                 static_cast<uint32_t>(os2->ulUnicodeRange3),
-                                 static_cast<uint32_t>(os2->ulUnicodeRange4)};
+
+#if defined(PDF_ENABLE_SKIA_TYPEFACE_CHECKS)
+#if defined(PDF_ENABLE_FONTATIONS)
+  std::optional<std::array<uint32_t, 4>> skrifa_result;
+  pdfium::span<const uint8_t> data = GetData();
+  skrifa::UnicodeRange range;
+  if (skrifa::get_os2_unicode_range(
+          rust::Slice<const uint8_t>(data.data(), data.size()), range)) {
+    skrifa_result = std::array<uint32_t, 4>{range.range1, range.range2,
+                                            range.range3, range.range4};
+  }
+  CHECK_EQ(ft_result.has_value(), skrifa_result.has_value());
+  if (ft_result.has_value() && skrifa_result.has_value()) {
+    for (size_t i = 0; i < 4; ++i) {
+      CHECK_EQ((*ft_result)[i], (*skrifa_result)[i]);
+    }
+  }
+#endif  // defined(PDF_ENABLE_FONTATIONS)
+#endif  // defined(PDF_ENABLE_SKIA_TYPEFACE_CHECKS)
+
+  return ft_result;
 }
 #endif  // defined(PDF_ENABLE_XFA)
 
@@ -976,7 +1010,21 @@
   char name[256] = {};
   FT_Get_Glyph_Name(GetRec(), glyph_index, name, sizeof(name));
   name[255] = 0;
-  return ByteString(name);
+  ByteString ft_result(name);
+
+#if defined(PDF_ENABLE_SKIA_TYPEFACE_CHECKS)
+#if defined(PDF_ENABLE_FONTATIONS)
+  pdfium::span<const uint8_t> data = GetData();
+  rust::String skrifa_result = skrifa::get_glyph_name(
+      rust::Slice<const uint8_t>(data.data(), data.size()), glyph_index);
+  CHECK_EQ(ft_result.IsEmpty(), skrifa_result.empty());
+  if (!ft_result.IsEmpty() && !skrifa_result.empty()) {
+    CHECK_EQ(ft_result, ByteString(skrifa_result.c_str()));
+  }
+#endif  // defined(PDF_ENABLE_FONTATIONS)
+#endif  // defined(PDF_ENABLE_SKIA_TYPEFACE_CHECKS)
+
+  return ft_result;
 }
 
 int CFX_Face::GetCharIndex(uint32_t code) {
@@ -1006,7 +1054,18 @@
 }
 
 int CFX_Face::GetNameIndex(const char* name) {
-  return FT_Get_Name_Index(GetRec(), name);
+  int ft_result = FT_Get_Name_Index(GetRec(), name);
+
+#if defined(PDF_ENABLE_SKIA_TYPEFACE_CHECKS)
+#if defined(PDF_ENABLE_FONTATIONS)
+  pdfium::span<const uint8_t> data = GetData();
+  uint32_t skrifa_result = skrifa::get_name_index(
+      rust::Slice<const uint8_t>(data.data(), data.size()), name);
+  CHECK_EQ(ft_result, static_cast<int>(skrifa_result));
+#endif  // defined(PDF_ENABLE_FONTATIONS)
+#endif  // defined(PDF_ENABLE_SKIA_TYPEFACE_CHECKS)
+
+  return ft_result;
 }
 
 int CFX_Face::LoadGlyph(uint32_t glyph_index, bool scale) {
diff --git a/core/fxge/skrifa/src/main.rs b/core/fxge/skrifa/src/main.rs
index 9cffdad..9c9f1a8 100644
--- a/core/fxge/skrifa/src/main.rs
+++ b/core/fxge/skrifa/src/main.rs
@@ -66,6 +66,14 @@
         pub b1: u8,
     }
 
+    #[derive(Copy, Clone, PartialEq, Eq, Debug)]
+    pub struct UnicodeRange {
+        pub range1: u32,
+        pub range2: u32,
+        pub range3: u32,
+        pub range4: u32,
+    }
+
     #[derive(Clone, Debug)]
     pub struct Outline {
         pub verbs: Vec<PathVerb>,
@@ -93,6 +101,10 @@
         fn get_os2_code_page_range(data: &[u8], range: &mut CodePageRange) -> bool;
         fn get_os2_panose(data: &[u8], panose: &mut Os2Panose) -> bool;
         fn get_os2_fs_type(data: &[u8], fs_type: &mut u16) -> bool;
+        fn get_os2_unicode_range(data: &[u8], range: &mut UnicodeRange) -> bool;
+        fn get_style_name(data: &[u8]) -> String;
+        fn get_glyph_name(data: &[u8], gid: u32) -> String;
+        fn get_name_index(data: &[u8], name: &str) -> u32;
 
         fn agl_name_to_unicode(name: &str, unicode: &mut u32) -> bool;
         fn agl_unicode_to_name(unicode: u32, name: &mut [u8]) -> bool;
@@ -370,6 +382,52 @@
     false
 }
 
+pub fn get_os2_unicode_range(data: &[u8], range: &mut skrifa_ffi::UnicodeRange) -> bool {
+    if let Ok(font) = read_fonts::FontRef::new(data) {
+        use read_fonts::TableProvider;
+        if let Ok(os2) = font.os2() {
+            range.range1 = os2.ul_unicode_range_1();
+            range.range2 = os2.ul_unicode_range_2();
+            range.range3 = os2.ul_unicode_range_3();
+            range.range4 = os2.ul_unicode_range_4();
+            return true;
+        }
+    }
+    false
+}
+
+pub fn get_style_name(data: &[u8]) -> String {
+    if let Ok(font) = skrifa::FontRef::new(data) {
+        use skrifa::string::StringId;
+        use skrifa::MetadataProvider;
+        if let Some(name) = font.localized_strings(StringId::SUBFAMILY_NAME).english_or_first() {
+            return name.to_string();
+        }
+    }
+    String::new()
+}
+
+pub fn get_glyph_name(data: &[u8], gid: u32) -> String {
+    if let Ok(font) = read_fonts::FontRef::new(data) {
+        let glyph_names = skrifa::GlyphNames::new(&font);
+        if let Some(name) = glyph_names.get(skrifa::GlyphId::new(gid)) {
+            return name.to_string();
+        }
+    }
+    String::new()
+}
+
+pub fn get_name_index(data: &[u8], name: &str) -> u32 {
+    if let Ok(font) = read_fonts::FontRef::new(data) {
+        let glyph_names = skrifa::GlyphNames::new(&font);
+        if let Some(gid) = glyph_names.iter().find(|(_id, n)| n.as_str() == name).map(|(id, _n)| id)
+        {
+            return gid.to_u32();
+        }
+    }
+    0
+}
+
 fn main() {
     skrifa_ffi::run("");
 }