Add public API for adding text with standard fonts

BUG=pdfium:667

Change-Id: I05e301385a7af4b6ce27dc0b885e23646abf3dd9
Reviewed-on: https://pdfium-review.googlesource.com/2711
Commit-Queue: dsinclair <dsinclair@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index dc06aa9..58f41ca 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -113,6 +113,7 @@
     "fpdfsdk/fpdfeditimg.cpp",
     "fpdfsdk/fpdfeditpage.cpp",
     "fpdfsdk/fpdfeditpath.cpp",
+    "fpdfsdk/fpdfedittext.cpp",
     "fpdfsdk/fpdfformfill.cpp",
     "fpdfsdk/fpdfppo.cpp",
     "fpdfsdk/fpdfsave.cpp",
diff --git a/fpdfsdk/fpdfedit_embeddertest.cpp b/fpdfsdk/fpdfedit_embeddertest.cpp
index 83d2631..fb56196 100644
--- a/fpdfsdk/fpdfedit_embeddertest.cpp
+++ b/fpdfsdk/fpdfedit_embeddertest.cpp
@@ -318,3 +318,63 @@
   FPDF_ClosePage(page);
   FPDF_CloseDocument(doc);
 }
+
+TEST_F(FPDFEditEmbeddertest, AddStandardFontText) {
+  // Start with a blank page
+  FPDF_DOCUMENT doc = FPDF_CreateNewDocument();
+  FPDF_PAGE page = FPDFPage_New(doc, 0, 612, 792);
+
+  // Add some text to the page
+  FPDF_PAGEOBJECT text1 = FPDFPageObj_NewTextObj(doc, "Arial", 12.0f);
+  EXPECT_TRUE(text1);
+  EXPECT_TRUE(FPDFText_SetText(text1, "I'm at the bottom of the page"));
+  FPDFPageObj_Transform(text1, 1, 0, 0, 1, 20, 20);
+  FPDFPage_InsertObject(page, text1);
+  EXPECT_TRUE(FPDFPage_GenerateContent(page));
+  FPDF_BITMAP page_bitmap = RenderPage(page);
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+  const char md5[] = "e19c90395d73cb9f37a6c3b0e8b18a9e";
+#else
+  const char md5[] = "7c3a36ba7cec01688a16a14bfed9ecfc";
+#endif
+  CompareBitmap(page_bitmap, 612, 792, md5);
+  FPDFBitmap_Destroy(page_bitmap);
+
+  // Try another font
+  FPDF_PAGEOBJECT text2 =
+      FPDFPageObj_NewTextObj(doc, "TimesNewRomanBold", 15.0f);
+  EXPECT_TRUE(text2);
+  EXPECT_TRUE(FPDFText_SetText(text2, "Hi, I'm Bold. Times New Roman Bold."));
+  FPDFPageObj_Transform(text2, 1, 0, 0, 1, 100, 600);
+  FPDFPage_InsertObject(page, text2);
+  EXPECT_TRUE(FPDFPage_GenerateContent(page));
+  page_bitmap = RenderPage(page);
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+  const char md5_2[] = "8e1c43dca6be68d364dbc283f5521041";
+#else
+  const char md5_2[] = "e0e0873e3a2634a6394a431a51ce90ff";
+#endif
+  CompareBitmap(page_bitmap, 612, 792, md5_2);
+  FPDFBitmap_Destroy(page_bitmap);
+
+  // And some randomly transformed text
+  FPDF_PAGEOBJECT text3 = FPDFPageObj_NewTextObj(doc, "Courier-Bold", 20.0f);
+  EXPECT_TRUE(text3);
+  EXPECT_TRUE(FPDFText_SetText(text3, "Can you read me? <:)>"));
+  FPDFPageObj_Transform(text3, 1, 1.5, 2, 0.5, 200, 200);
+  FPDFPage_InsertObject(page, text3);
+  EXPECT_TRUE(FPDFPage_GenerateContent(page));
+  page_bitmap = RenderPage(page);
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+  const char md5_3[] = "c6e5df448428793c7e4b0c820bd8c85e";
+#else
+  const char md5_3[] = "903ee10b6a9f0be51ecad0a1a0eeb171";
+#endif
+  CompareBitmap(page_bitmap, 612, 792, md5_3);
+  FPDFBitmap_Destroy(page_bitmap);
+
+  // TODO(npm): Why are there issues with text rotated by 90 degrees?
+  // TODO(npm): FPDF_SaveAsCopy not giving the desired result after this.
+  FPDF_ClosePage(page);
+  FPDF_CloseDocument(doc);
+}
diff --git a/fpdfsdk/fpdfedittext.cpp b/fpdfsdk/fpdfedittext.cpp
new file mode 100644
index 0000000..79ca310
--- /dev/null
+++ b/fpdfsdk/fpdfedittext.cpp
@@ -0,0 +1,38 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "public/fpdf_edit.h"
+
+#include "core/fpdfapi/cpdf_modulemgr.h"
+#include "core/fpdfapi/font/cpdf_font.h"
+#include "core/fpdfapi/page/cpdf_textobject.h"
+#include "fpdfsdk/fsdk_define.h"
+
+DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_NewTextObj(FPDF_DOCUMENT document,
+                                                         FPDF_BYTESTRING font,
+                                                         float font_size) {
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
+  if (!pDoc)
+    return nullptr;
+
+  CPDF_Font* pFont = CPDF_Font::GetStockFont(pDoc, CFX_ByteStringC(font));
+  if (!pFont)
+    return nullptr;
+
+  CPDF_TextObject* pTextObj = new CPDF_TextObject;
+  pTextObj->m_TextState.SetFont(pFont);
+  pTextObj->m_TextState.SetFontSize(font_size);
+  pTextObj->DefaultStates();
+  return pTextObj;
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FPDFText_SetText(FPDF_PAGEOBJECT text_object,
+                                             FPDF_BYTESTRING text) {
+  if (!text_object)
+    return false;
+
+  auto pTextObj = reinterpret_cast<CPDF_TextObject*>(text_object);
+  pTextObj->SetText(CFX_ByteString(text));
+  return true;
+}
\ No newline at end of file
diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h
index a43d181..c8d7a44 100644
--- a/public/fpdf_edit.h
+++ b/public/fpdf_edit.h
@@ -386,6 +386,26 @@
                                          int fillmode,
                                          FPDF_BOOL stroke);
 
+// Create a new text object using one of the standard PDF fonts.
+//
+// document   - handle to the document.
+// font       - string containing the font name, without spaces.
+// font_size  - the font size for the new text object.
+//
+// Returns a handle to a new text object, or NULL on failure
+DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_NewTextObj(FPDF_DOCUMENT document,
+                                                         FPDF_BYTESTRING font,
+                                                         float font_size);
+
+// Set the text for a textobject. If it had text, it will be replaced.
+//
+// text_object  - handle to the text object.
+// text         - string containing the text to be added.
+//
+// Returns TRUE on success
+DLLEXPORT FPDF_BOOL STDCALL FPDFText_SetText(FPDF_PAGEOBJECT text_object,
+                                             FPDF_BYTESTRING text);
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif  // __cplusplus