Add experimental FPDFFont_GetBaseName() API

Add an API that is nearly identical to FPDFFont_GetFamilyName(), but
returns the base name instead. This API matches the behavior of
FPDFText_GetFontInfo() and is a suitable replacement.

Bug: 353746891
Change-Id: Iaffc8e80b77be720f1d74fe8fb4ddf9671e05fac
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/121895
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Tom Sepez <tsepez@google.com>
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp
index 972b204..fba054b 100644
--- a/fpdfsdk/fpdf_edit_embeddertest.cpp
+++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -2924,6 +2924,7 @@
 TEST_F(FPDFEditEmbedderTest, TextFontProperties) {
   // bad object tests
   EXPECT_FALSE(FPDFTextObj_GetFont(nullptr));
+  EXPECT_EQ(0U, FPDFFont_GetBaseName(nullptr, nullptr, 5));
   EXPECT_EQ(0U, FPDFFont_GetFamilyName(nullptr, nullptr, 5));
   EXPECT_EQ(-1, FPDFFont_GetFlags(nullptr));
   EXPECT_EQ(-1, FPDFFont_GetWeight(nullptr));
@@ -2977,6 +2978,26 @@
   }
 
   {
+    // FPDFFont_GetBaseName() positive testing.
+    unsigned long size = FPDFFont_GetBaseName(font, nullptr, 0);
+    const char kExpectedFontName[] = "LiberationSerif";
+    ASSERT_EQ(sizeof(kExpectedFontName), size);
+    std::vector<char> font_name(size);
+    ASSERT_EQ(size, FPDFFont_GetBaseName(font, font_name.data(), size));
+    ASSERT_STREQ(kExpectedFontName, font_name.data());
+
+    // FPDFFont_GetBaseName() negative testing.
+    ASSERT_EQ(0U, FPDFFont_GetBaseName(nullptr, nullptr, 0));
+
+    font_name.resize(2);
+    font_name[0] = 'x';
+    font_name[1] = '\0';
+    size = FPDFFont_GetBaseName(font, font_name.data(), font_name.size());
+    ASSERT_EQ(sizeof(kExpectedFontName), size);
+    ASSERT_STREQ("x", font_name.data());
+  }
+
+  {
     // FPDFFont_GetFamilyName() positive testing.
     unsigned long size = FPDFFont_GetFamilyName(font, nullptr, 0);
     const char kExpectedFontName[] = "Liberation Serif";
diff --git a/fpdfsdk/fpdf_edittext.cpp b/fpdfsdk/fpdf_edittext.cpp
index 6e9a586..482f845 100644
--- a/fpdfsdk/fpdf_edittext.cpp
+++ b/fpdfsdk/fpdf_edittext.cpp
@@ -849,6 +849,22 @@
   return FPDFFontFromCPDFFont(pTextObj->GetFont());
 }
 
+FPDF_EXPORT size_t FPDF_CALLCONV FPDFFont_GetBaseName(FPDF_FONT font,
+                                                      char* buffer,
+                                                      size_t length) {
+  auto* cfont = CPDFFontFromFPDFFont(font);
+  if (!cfont) {
+    return 0;
+  }
+
+  // SAFETY: required from caller.
+  auto result_span = UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, length));
+  ByteString name = cfont->GetFont()->GetBaseFontName();
+  pdfium::span<const char> name_span = name.span_with_terminator();
+  fxcrt::try_spancpy(result_span, name_span);
+  return name_span.size();
+}
+
 FPDF_EXPORT size_t FPDF_CALLCONV FPDFFont_GetFamilyName(FPDF_FONT font,
                                                         char* buffer,
                                                         size_t length) {
diff --git a/fpdfsdk/fpdf_view_c_api_test.c b/fpdfsdk/fpdf_view_c_api_test.c
index f30160c..7018331 100644
--- a/fpdfsdk/fpdf_view_c_api_test.c
+++ b/fpdfsdk/fpdf_view_c_api_test.c
@@ -163,6 +163,7 @@
     // fpdf_edit.h
     CHK(FPDFFont_Close);
     CHK(FPDFFont_GetAscent);
+    CHK(FPDFFont_GetBaseName);
     CHK(FPDFFont_GetDescent);
     CHK(FPDFFont_GetFamilyName);
     CHK(FPDFFont_GetFlags);
diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h
index 2c758f3..19eee7f 100644
--- a/public/fpdf_edit.h
+++ b/public/fpdf_edit.h
@@ -1365,6 +1365,24 @@
 FPDF_EXPORT FPDF_FONT FPDF_CALLCONV FPDFTextObj_GetFont(FPDF_PAGEOBJECT text);
 
 // Experimental API.
+// Get the base name of a font.
+//
+// font   - the handle to the font object.
+// buffer - the address of a buffer that receives the base font name.
+// length - the size, in bytes, of |buffer|.
+//
+// Returns the number of bytes in the base name (including the trailing NUL
+// character) on success, 0 on error. The base name is typically the font's
+// PostScript name.
+//
+// Regardless of the platform, the |buffer| is always in UTF-8 encoding.
+// If |length| is less than the returned length, or |buffer| is NULL, |buffer|
+// will not be modified.
+FPDF_EXPORT size_t FPDF_CALLCONV FPDFFont_GetBaseName(FPDF_FONT font,
+                                                      char* buffer,
+                                                      size_t length);
+
+// Experimental API.
 // Get the family name of a font.
 //
 // font   - the handle to the font object.