Use Optional to determine if appearance stream as font

This CL changes the CPDF_DefaultAppearance code to remove the HasFont
method and change GetFont to return an Optional. This forces all the
call sites to verify a font was returned correctly and removes the need
for the duplicate appearance stream parsing.

Bug: chromium:827430
Change-Id: If09e0a7d3f7dd63ad77b97a5a388127e4a02da61
Reviewed-on: https://pdfium-review.googlesource.com/29610
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
diff --git a/core/fpdfdoc/cpdf_defaultappearance.cpp b/core/fpdfdoc/cpdf_defaultappearance.cpp
index add1c26..161f90e 100644
--- a/core/fpdfdoc/cpdf_defaultappearance.cpp
+++ b/core/fpdfdoc/cpdf_defaultappearance.cpp
@@ -53,18 +53,10 @@
 
 }  // namespace
 
-bool CPDF_DefaultAppearance::HasFont() {
-  if (m_csDA.IsEmpty())
-    return false;
-
-  CPDF_SimpleParser syntax(m_csDA.AsStringView());
-  return FindTagParamFromStart(&syntax, "Tf", 2);
-}
-
-ByteString CPDF_DefaultAppearance::GetFont(float* fFontSize) {
+Optional<ByteString> CPDF_DefaultAppearance::GetFont(float* fFontSize) {
   *fFontSize = 0.0f;
   if (m_csDA.IsEmpty())
-    return ByteString();
+    return {};
 
   ByteString csFontNameTag;
   CPDF_SimpleParser syntax(m_csDA.AsStringView());
@@ -73,7 +65,7 @@
     csFontNameTag.Delete(0, 1);
     *fFontSize = FX_atof(syntax.GetWord());
   }
-  return PDF_NameDecode(csFontNameTag.AsStringView());
+  return {PDF_NameDecode(csFontNameTag.AsStringView())};
 }
 
 bool CPDF_DefaultAppearance::HasColor() {
diff --git a/core/fpdfdoc/cpdf_defaultappearance.h b/core/fpdfdoc/cpdf_defaultappearance.h
index 7957893..ae3c4f5 100644
--- a/core/fpdfdoc/cpdf_defaultappearance.h
+++ b/core/fpdfdoc/cpdf_defaultappearance.h
@@ -25,8 +25,7 @@
   CPDF_DefaultAppearance(const CPDF_DefaultAppearance& cDA)
       : m_csDA(cDA.m_csDA) {}
 
-  bool HasFont();
-  ByteString GetFont(float* fFontSize);
+  Optional<ByteString> GetFont(float* fFontSize);
 
   bool HasColor();
   CFX_Color::Type GetColor(float fc[4]);
diff --git a/core/fpdfdoc/cpdf_formcontrol.cpp b/core/fpdfdoc/cpdf_formcontrol.cpp
index 384c35e..a78a24d 100644
--- a/core/fpdfdoc/cpdf_formcontrol.cpp
+++ b/core/fpdfdoc/cpdf_formcontrol.cpp
@@ -277,15 +277,15 @@
 CPDF_Font* CPDF_FormControl::GetDefaultControlFont() {
   float fFontSize;
   CPDF_DefaultAppearance cDA = GetDefaultAppearance();
-  ByteString csFontNameTag = cDA.GetFont(&fFontSize);
-  if (csFontNameTag.IsEmpty())
+  Optional<ByteString> csFontNameTag = cDA.GetFont(&fFontSize);
+  if (!csFontNameTag || csFontNameTag->IsEmpty())
     return nullptr;
 
   CPDF_Object* pObj = FPDF_GetFieldAttr(m_pWidgetDict.Get(), "DR");
   if (CPDF_Dictionary* pDict = ToDictionary(pObj)) {
     CPDF_Dictionary* pFonts = pDict->GetDictFor("Font");
     if (pFonts) {
-      CPDF_Dictionary* pElement = pFonts->GetDictFor(csFontNameTag);
+      CPDF_Dictionary* pElement = pFonts->GetDictFor(*csFontNameTag);
       if (pElement) {
         CPDF_Font* pFont =
             m_pField->GetForm()->GetDocument()->LoadFont(pElement);
@@ -294,7 +294,7 @@
       }
     }
   }
-  if (CPDF_Font* pFormFont = m_pField->GetForm()->GetFormFont(csFontNameTag))
+  if (CPDF_Font* pFormFont = m_pField->GetForm()->GetFormFont(*csFontNameTag))
     return pFormFont;
 
   CPDF_Dictionary* pPageDict = m_pWidgetDict->GetDictFor("P");
@@ -302,7 +302,7 @@
   if (CPDF_Dictionary* pDict = ToDictionary(pObj)) {
     CPDF_Dictionary* pFonts = pDict->GetDictFor("Font");
     if (pFonts) {
-      CPDF_Dictionary* pElement = pFonts->GetDictFor(csFontNameTag);
+      CPDF_Dictionary* pElement = pFonts->GetDictFor(*csFontNameTag);
       if (pElement) {
         CPDF_Font* pFont =
             m_pField->GetForm()->GetDocument()->LoadFont(pElement);
diff --git a/core/fpdfdoc/cpdf_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp
index f3dcac2..540e1c9a 100644
--- a/core/fpdfdoc/cpdf_formfield.cpp
+++ b/core/fpdfdoc/cpdf_formfield.cpp
@@ -915,11 +915,11 @@
     return;
 
   CPDF_DefaultAppearance appearance(DA);
-  if (!appearance.HasFont())
+  Optional<ByteString> font_name = appearance.GetFont(&m_FontSize);
+  if (!font_name)
     return;
 
-  ByteString font_name = appearance.GetFont(&m_FontSize);
-  CPDF_Dictionary* pFontDict = pFont->GetDictFor(font_name);
+  CPDF_Dictionary* pFontDict = pFont->GetDictFor(*font_name);
   if (!pFontDict)
     return;
 
diff --git a/core/fpdfdoc/cpvt_generateap.cpp b/core/fpdfdoc/cpvt_generateap.cpp
index a6a64aa..ef55545 100644
--- a/core/fpdfdoc/cpvt_generateap.cpp
+++ b/core/fpdfdoc/cpvt_generateap.cpp
@@ -923,13 +923,13 @@
     return;
 
   CPDF_DefaultAppearance appearance(DA);
-  if (!appearance.HasFont())
+
+  float fFontSize = 0;
+  Optional<ByteString> font = appearance.GetFont(&fFontSize);
+  if (!font)
     return;
 
-  ASSERT(appearance.HasFont());
-  float fFontSize = 0;
-  ByteString sFontName =
-      PDF_NameDecode(appearance.GetFont(&fFontSize).AsStringView());
+  ByteString sFontName = PDF_NameDecode(font->AsStringView());
   if (sFontName.IsEmpty())
     return;
 
diff --git a/fpdfsdk/formfiller/cba_fontmap.cpp b/fpdfsdk/formfiller/cba_fontmap.cpp
index b7e14b4..0daa0cd 100644
--- a/fpdfsdk/formfiller/cba_fontmap.cpp
+++ b/fpdfsdk/formfiller/cba_fontmap.cpp
@@ -217,12 +217,14 @@
     return nullptr;
 
   CPDF_DefaultAppearance appearance(sDA);
-  ASSERT(appearance.HasFont());
-
   float font_size;
-  ByteString sDecodedFontName =
-      PDF_NameDecode(appearance.GetFont(&font_size).AsStringView());
-  *sAlias = sDecodedFontName.Right(sDecodedFontName.GetLength() - 1);
+  Optional<ByteString> font = appearance.GetFont(&font_size);
+  if (font) {
+    ByteString sDecodedFontName = PDF_NameDecode(font->AsStringView());
+    *sAlias = sDecodedFontName.Right(sDecodedFontName.GetLength() - 1);
+  } else {
+    *sAlias = ByteString();
+  }
 
   CPDF_Dictionary* pFontDict = nullptr;
   if (CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictFor("AP")) {
diff --git a/fpdfsdk/pwl/cpwl_appstream.cpp b/fpdfsdk/pwl/cpwl_appstream.cpp
index 0731398..6e65831 100644
--- a/fpdfsdk/pwl/cpwl_appstream.cpp
+++ b/fpdfsdk/pwl/cpwl_appstream.cpp
@@ -1184,9 +1184,13 @@
     iColorType = da.GetColor(fc);
     crText = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
   }
-  float fFontSize = 12.0f;
-  if (da.HasFont())
-    csNameTag = da.GetFont(&fFontSize);
+
+  float fFontSize;
+  Optional<ByteString> font = da.GetFont(&fFontSize);
+  if (font)
+    csNameTag = *font;
+  else
+    fFontSize = 12.0f;
 
   WideString csWCaption;
   WideString csNormalCaption;