Add freetext annotation support to FPDFAnnot_GetFontColor()

FPDFAnnot_GetFontColor() currently only supports widgets with variable
text. Freetext annotation also has variable text, so it should work with
FPDFAnnot_GetFontColor() as well.

Bug: 419321436
Change-Id: I9db634fd88396b8ee0b60530bb8ce877725d49cf
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/131952
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfdoc/cpdf_defaultappearance.cpp b/core/fpdfdoc/cpdf_defaultappearance.cpp
index ed934d2..94e56e4 100644
--- a/core/fpdfdoc/cpdf_defaultappearance.cpp
+++ b/core/fpdfdoc/cpdf_defaultappearance.cpp
@@ -27,7 +27,7 @@
   if (default_appearance_object) {
     default_appearance_string = default_appearance_object->GetString();
   }
-  if (default_appearance_string.IsEmpty()) {
+  if (default_appearance_string.IsEmpty() && acroform_dict) {
     default_appearance_string = acroform_dict->GetByteStringFor("DA");
   }
   return default_appearance_string;
diff --git a/fpdfsdk/fpdf_annot.cpp b/fpdfsdk/fpdf_annot.cpp
index 2ead581..e8e69ee 100644
--- a/fpdfsdk/fpdf_annot.cpp
+++ b/fpdfsdk/fpdf_annot.cpp
@@ -357,6 +357,27 @@
                     : nullptr;
 }
 
+std::optional<CFX_Color::TypeAndARGB> GetFreetextFontColor(
+    FPDF_FORMHANDLE handle,
+    FPDF_ANNOTATION annot) {
+  const CPDF_Dictionary* annot_dict = GetAnnotDictFromFPDFAnnotation(annot);
+  CHECK(annot_dict);  // Has to be true to determine `annot` is for Freetext.
+
+  CPDFSDK_InteractiveForm* form = FormHandleToInteractiveForm(handle);
+  CPDF_Document* doc = form ? form->GetInteractiveForm()->document() : nullptr;
+  const CPDF_Dictionary* root_dict = doc ? doc->GetRoot() : nullptr;
+  RetainPtr<const CPDF_Dictionary> acroform_dict =
+      root_dict ? root_dict->GetDictFor("AcroForm") : nullptr;
+  CPDF_DefaultAppearance default_appearance(annot_dict, acroform_dict);
+  return default_appearance.GetColorARGB();
+}
+
+std::optional<FX_COLORREF> GetWidgetFontColor(FPDF_FORMHANDLE handle,
+                                              FPDF_ANNOTATION annot) {
+  const CPDFSDK_Widget* widget = GetWidgetOfTypes(handle, annot, {});
+  return widget ? widget->GetTextColor() : std::nullopt;
+}
+
 }  // namespace
 
 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
@@ -1533,19 +1554,32 @@
     return false;
   }
 
-  const CPDFSDK_Widget* widget = GetWidgetOfTypes(hHandle, annot, {});
-  if (!widget) {
-    return false;
+  FX_COLORREF font_color;
+  switch (FPDFAnnot_GetSubtype(annot)) {
+    case FPDF_ANNOT_FREETEXT: {
+      auto maybe_font_color = GetFreetextFontColor(hHandle, annot);
+      if (!maybe_font_color.has_value()) {
+        return false;
+      }
+      font_color = ArgbToColorRef(maybe_font_color.value().argb);
+      break;
+    }
+    case FPDF_ANNOT_WIDGET: {
+      auto maybe_font_color = GetWidgetFontColor(hHandle, annot);
+      if (!maybe_font_color.has_value()) {
+        return false;
+      }
+      font_color = maybe_font_color.value();
+      break;
+    }
+    default: {
+      return false;
+    }
   }
 
-  std::optional<FX_COLORREF> text_color = widget->GetTextColor();
-  if (!text_color) {
-    return false;
-  }
-
-  *R = FXSYS_GetRValue(*text_color);
-  *G = FXSYS_GetGValue(*text_color);
-  *B = FXSYS_GetBValue(*text_color);
+  *R = FXSYS_GetRValue(font_color);
+  *G = FXSYS_GetGValue(font_color);
+  *B = FXSYS_GetBValue(font_color);
   return true;
 }
 
diff --git a/fpdfsdk/fpdf_annot_embeddertest.cpp b/fpdfsdk/fpdf_annot_embeddertest.cpp
index 0417f74..fb33ce1 100644
--- a/fpdfsdk/fpdf_annot_embeddertest.cpp
+++ b/fpdfsdk/fpdf_annot_embeddertest.cpp
@@ -2792,10 +2792,22 @@
     ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page.get(), 0));
     ASSERT_TRUE(annot);
 
-    // TODO(thestig): Check FPDFAnnot_GetFontColor() results before and after,
-    // when the API supports freetext annotations.
+    unsigned int r = 1;
+    unsigned int g = 2;
+    unsigned int b = 3;
+    ASSERT_TRUE(FPDFAnnot_GetFontColor(form_handle(), annot.get(), &r, &g, &b));
+    EXPECT_EQ(0u, r);
+    EXPECT_EQ(0u, g);
+    EXPECT_EQ(0u, b);
+
     ASSERT_TRUE(
         FPDFAnnot_SetFontColor(form_handle(), annot.get(), 60, 120, 180));
+
+    ASSERT_TRUE(FPDFAnnot_GetFontColor(form_handle(), annot.get(), &r, &g, &b));
+    EXPECT_EQ(60u, r);
+    EXPECT_EQ(120u, g);
+    EXPECT_EQ(180u, b);
+
     bitmap = RenderLoadedPageWithFlags(page.get(), FPDF_ANNOT);
     CompareBitmap(bitmap.get(), kDimension, kDimension, modified_checksum);
   }