New FPDFText_GetTextRenderMode API

Added a new API to get the text rendering mode of a specific character.
Also added a typedef FPDF_TEXT_RENDERMODE (int).

Change-Id: If7b98890640bcfdebb90e5f81a7fb633944acd96
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/60410
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_textobject.cpp b/core/fpdfapi/page/cpdf_textobject.cpp
index fb365ac..afae35b 100644
--- a/core/fpdfapi/page/cpdf_textobject.cpp
+++ b/core/fpdfapi/page/cpdf_textobject.cpp
@@ -253,6 +253,10 @@
   return m_TextState.GetFontSize();
 }
 
+TextRenderingMode CPDF_TextObject::GetTextRenderMode() const {
+  return m_TextState.GetTextMode();
+}
+
 CFX_PointF CPDF_TextObject::CalcPositionData(float horz_scale) {
   float curpos = 0;
   float min_x = 10000 * 1.0f;
diff --git a/core/fpdfapi/page/cpdf_textobject.h b/core/fpdfapi/page/cpdf_textobject.h
index b0189a9..1717256 100644
--- a/core/fpdfapi/page/cpdf_textobject.h
+++ b/core/fpdfapi/page/cpdf_textobject.h
@@ -55,6 +55,8 @@
   RetainPtr<CPDF_Font> GetFont() const;
   float GetFontSize() const;
 
+  TextRenderingMode GetTextRenderMode() const;
+
   void SetText(const ByteString& str);
   void SetPosition(CFX_PointF pos) { m_Pos = pos; }
   void SetPosition(float x, float y);
diff --git a/fpdfsdk/fpdf_edittext.cpp b/fpdfsdk/fpdf_edittext.cpp
index 2ca8faa..9ed5601 100644
--- a/fpdfsdk/fpdf_edittext.cpp
+++ b/fpdfsdk/fpdf_edittext.cpp
@@ -590,8 +590,10 @@
   return FPDFPageObjectFromCPDFPageObject(pTextObj.release());
 }
 
-FPDF_EXPORT int FPDF_CALLCONV
+FPDF_EXPORT FPDF_TEXT_RENDERMODE FPDF_CALLCONV
 FPDFTextObj_GetTextRenderMode(FPDF_PAGEOBJECT text) {
   CPDF_TextObject* pTextObj = CPDFTextObjectFromFPDFPageObject(text);
-  return pTextObj ? static_cast<int>(pTextObj->m_TextState.GetTextMode()) : -1;
+  if (!pTextObj)
+    return -1;
+  return static_cast<FPDF_TEXT_RENDERMODE>(pTextObj->m_TextState.GetTextMode());
 }
diff --git a/fpdfsdk/fpdf_text.cpp b/fpdfsdk/fpdf_text.cpp
index a635847..4d29d61 100644
--- a/fpdfsdk/fpdf_text.cpp
+++ b/fpdfsdk/fpdf_text.cpp
@@ -129,6 +129,21 @@
   return charinfo.m_pTextObj->GetFont()->GetFontWeight();
 }
 
+FPDF_EXPORT FPDF_TEXT_RENDERMODE FPDF_CALLCONV
+FPDFText_GetTextRenderMode(FPDF_TEXTPAGE text_page, int index) {
+  CPDF_TextPage* textpage = GetTextPageForValidIndex(text_page, index);
+  if (!textpage)
+    return -1;
+
+  FPDF_CHAR_INFO charinfo;
+  textpage->GetCharInfo(index, &charinfo);
+  if (!charinfo.m_pTextObj)
+    return -1;
+
+  return static_cast<FPDF_TEXT_RENDERMODE>(
+      charinfo.m_pTextObj->GetTextRenderMode());
+}
+
 FPDF_EXPORT double FPDF_CALLCONV FPDFText_GetCharAngle(FPDF_TEXTPAGE text_page,
                                                        int index) {
   CPDF_TextPage* textpage = GetTextPageForValidIndex(text_page, index);
diff --git a/fpdfsdk/fpdf_text_embeddertest.cpp b/fpdfsdk/fpdf_text_embeddertest.cpp
index 8f00b60..40d0c97 100644
--- a/fpdfsdk/fpdf_text_embeddertest.cpp
+++ b/fpdfsdk/fpdf_text_embeddertest.cpp
@@ -1274,3 +1274,26 @@
   FPDFText_ClosePage(text_page);
   UnloadPage(page);
 }
+
+TEST_F(FPDFTextEmbedderTest, GetTextRenderMode) {
+  EXPECT_TRUE(OpenDocument("text_render_mode.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  ASSERT_TRUE(page);
+
+  FPDF_TEXTPAGE text_page = FPDFText_LoadPage(page);
+  ASSERT_TRUE(text_page);
+
+  ASSERT_EQ(12, FPDFText_CountChars(text_page));
+
+  ASSERT_EQ(-1, FPDFText_GetTextRenderMode(nullptr, 0));
+  ASSERT_EQ(-1, FPDFText_GetTextRenderMode(text_page, -1));
+  ASSERT_EQ(-1, FPDFText_GetTextRenderMode(text_page, 314));
+
+  ASSERT_EQ(FPDF_TEXTRENDERMODE_FILL, FPDFText_GetTextRenderMode(text_page, 0));
+
+  ASSERT_EQ(FPDF_TEXTRENDERMODE_STROKE,
+            FPDFText_GetTextRenderMode(text_page, 7));
+
+  FPDFText_ClosePage(text_page);
+  UnloadPage(page);
+}
diff --git a/fpdfsdk/fpdf_view_c_api_test.c b/fpdfsdk/fpdf_view_c_api_test.c
index ad77fa1..1e00348 100644
--- a/fpdfsdk/fpdf_view_c_api_test.c
+++ b/fpdfsdk/fpdf_view_c_api_test.c
@@ -343,6 +343,7 @@
     CHK(FPDFText_GetSchCount);
     CHK(FPDFText_GetSchResultIndex);
     CHK(FPDFText_GetText);
+    CHK(FPDFText_GetTextRenderMode);
     CHK(FPDFText_GetUnicode);
     CHK(FPDFText_LoadPage);
 
diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h
index 335c703..5974ab6 100644
--- a/public/fpdf_edit.h
+++ b/public/fpdf_edit.h
@@ -70,15 +70,6 @@
 #define FPDF_PRINTMODE_POSTSCRIPT2_PASSTHROUGH 4
 #define FPDF_PRINTMODE_POSTSCRIPT3_PASSTHROUGH 5
 
-#define FPDF_TEXTRENDERMODE_FILL 0
-#define FPDF_TEXTRENDERMODE_STROKE 1
-#define FPDF_TEXTRENDERMODE_FILL_STROKE 2
-#define FPDF_TEXTRENDERMODE_INVISIBLE 3
-#define FPDF_TEXTRENDERMODE_FILL_CLIP 4
-#define FPDF_TEXTRENDERMODE_STROKE_CLIP 5
-#define FPDF_TEXTRENDERMODE_FILL_STROKE_CLIP 6
-#define FPDF_TEXTRENDERMODE_CLIP 7
-
 typedef struct FPDF_IMAGEOBJ_METADATA {
   // The image width in pixels.
   unsigned int width;
@@ -1173,7 +1164,7 @@
 // text     - the handle to the text object.
 //
 // Returns one of the FPDF_TEXTRENDERMODE_* flags on success, -1 on error.
-FPDF_EXPORT int FPDF_CALLCONV
+FPDF_EXPORT FPDF_TEXT_RENDERMODE FPDF_CALLCONV
 FPDFTextObj_GetTextRenderMode(FPDF_PAGEOBJECT text);
 
 // Experimental API.
diff --git a/public/fpdf_text.h b/public/fpdf_text.h
index 6e454d1..c7e9d71 100644
--- a/public/fpdf_text.h
+++ b/public/fpdf_text.h
@@ -128,6 +128,20 @@
                                                      int index);
 
 // Experimental API.
+// Function: FPDFText_GetTextRenderMode
+//          Get text rendering mode of character.
+// Parameters:
+//          text_page   -   Handle to a text page information structure.
+//                          Returned by FPDFText_LoadPage function.
+//          index       -   Zero-based index of the character.
+// Return Value:
+//          On success, return the render mode value. A valid value is of type
+//          FPDF_TEXT_RENDERMODE. If |text_page| is invalid, if |index| is out
+//          of bounds, or if the text object is undefined, then return -1.
+FPDF_EXPORT FPDF_TEXT_RENDERMODE FPDF_CALLCONV
+FPDFText_GetTextRenderMode(FPDF_TEXTPAGE text_page, int index);
+
+// Experimental API.
 // Function: FPDFText_GetCharAngle
 //          Get character rotation angle.
 // Parameters:
diff --git a/public/fpdfview.h b/public/fpdfview.h
index f8c6a99..84ba789 100644
--- a/public/fpdfview.h
+++ b/public/fpdfview.h
@@ -34,6 +34,16 @@
 #define FPDF_OBJECT_NULLOBJ 8
 #define FPDF_OBJECT_REFERENCE 9
 
+// PDF text rendering modes
+#define FPDF_TEXTRENDERMODE_FILL 0
+#define FPDF_TEXTRENDERMODE_STROKE 1
+#define FPDF_TEXTRENDERMODE_FILL_STROKE 2
+#define FPDF_TEXTRENDERMODE_INVISIBLE 3
+#define FPDF_TEXTRENDERMODE_FILL_CLIP 4
+#define FPDF_TEXTRENDERMODE_STROKE_CLIP 5
+#define FPDF_TEXTRENDERMODE_FILL_STROKE_CLIP 6
+#define FPDF_TEXTRENDERMODE_CLIP 7
+
 // PDF types - use incomplete types (never completed) just for API type safety.
 typedef struct fpdf_action_t__* FPDF_ACTION;
 typedef struct fpdf_annotation_t__* FPDF_ANNOTATION;
@@ -155,6 +165,9 @@
 // Dictionary value types.
 typedef int FPDF_OBJECT_TYPE;
 
+// Text object enums.
+typedef int FPDF_TEXT_RENDERMODE;
+
 #if defined(COMPONENT_BUILD)
 // FPDF_EXPORT should be consistent with |export| in the pdfium_fuzzer
 // template in testing/fuzzers/BUILD.gn.