Add a ToUnicode mapping when loading CID fonts

This CL adds ToUnicode for CID fonts and adds a test to prove that using it
works as intended. The test uses a Linux font for Japanese characters, and
tests for other OS will be added in a followup.

The ToUnicode works by defining the PDF charcodes as equal to the glyph indices
and assuming that the freetype charcodes given by FXFT_Get_Next_Char are in
fact the unicode values.

Bug: pdfium:667
Change-Id: I419724b87c3936c730a05f771548ae4787a576eb
Reviewed-on: https://pdfium-review.googlesource.com/4810
Commit-Queue: Nicolás Peña <npm@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
diff --git a/fpdfsdk/fpdfedit_embeddertest.cpp b/fpdfsdk/fpdfedit_embeddertest.cpp
index 01ac01e..383e207 100644
--- a/fpdfsdk/fpdfedit_embeddertest.cpp
+++ b/fpdfsdk/fpdfedit_embeddertest.cpp
@@ -646,21 +646,7 @@
   // Check widths
   CPDF_Array* widths_array = cidfont_dict->GetArrayFor("W");
   ASSERT_TRUE(widths_array);
-  // Note: widths can be described in different ways in the widths array. The
-  // following checks are specific to our current implementation.
-  EXPECT_EQ(32, widths_array->GetNumberAt(0));
-  CPDF_Array* arr = widths_array->GetArrayAt(1);
-  ASSERT_TRUE(arr);
-  // This font support chars 32 to 126
-  EXPECT_EQ(95U, arr->GetCount());
-  EXPECT_EQ(250, arr->GetNumberAt(0));
-  EXPECT_EQ(610, arr->GetNumberAt(44));
-  EXPECT_EQ(541, arr->GetNumberAt(94));
-  // Next range: 160 - 383
-  EXPECT_EQ(160, widths_array->GetNumberAt(2));
-  arr = widths_array->GetArrayAt(3);
-  ASSERT_TRUE(arr);
-
+  EXPECT_GT(widths_array->GetCount(), 1U);
   CheckCompositeFontWidths(widths_array, typed_font);
 }
 
@@ -786,3 +772,77 @@
   FPDF_ClosePage(new_page);
   FPDF_CloseDocument(new_doc);
 }
+
+// TODO(npm): Add tests using Japanese fonts in other OS.
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_
+TEST_F(FPDFEditEmbeddertest, AddCIDFontText) {
+  // Start with a blank page
+  FPDF_PAGE page = FPDFPage_New(CreateNewDocument(), 0, 612, 792);
+  CFX_Font CIDfont;
+  {
+    // First, get the data from the font
+    CIDfont.LoadSubst("IPAGothic", 1, 0, 400, 0, 932, 0);
+    EXPECT_EQ("IPAGothic", CIDfont.GetFaceName());
+    const uint8_t* data = CIDfont.GetFontData();
+    const uint32_t size = CIDfont.GetSize();
+
+    // Load the data into a FPDF_Font.
+    std::unique_ptr<void, FPDFFontDeleter> font(
+        FPDFText_LoadFont(document(), data, size, FPDF_FONT_TRUETYPE, 1));
+    ASSERT_TRUE(font.get());
+
+    // Add some text to the page
+    FPDF_PAGEOBJECT text_object =
+        FPDFPageObj_CreateTextObj(document(), font.get(), 12.0f);
+    ASSERT_TRUE(text_object);
+    std::wstring wstr = L"ABCDEFGhijklmnop.";
+    std::unique_ptr<unsigned short, pdfium::FreeDeleter> text =
+        GetFPDFWideString(wstr);
+    EXPECT_TRUE(FPDFText_SetText(text_object, text.get()));
+    FPDFPageObj_Transform(text_object, 1, 0, 0, 1, 200, 200);
+    FPDFPage_InsertObject(page, text_object);
+
+    // And add some Japanese characters
+    FPDF_PAGEOBJECT text_object2 =
+        FPDFPageObj_CreateTextObj(document(), font.get(), 18.0f);
+    ASSERT_TRUE(text_object2);
+    std::wstring wstr2 =
+        L"\u3053\u3093\u306B\u3061\u306f\u4e16\u754C\u3002\u3053\u3053\u306B1"
+        L"\u756A";
+    std::unique_ptr<unsigned short, pdfium::FreeDeleter> text2 =
+        GetFPDFWideString(wstr2);
+    EXPECT_TRUE(FPDFText_SetText(text_object2, text2.get()));
+    FPDFPageObj_Transform(text_object2, 1, 0, 0, 1, 100, 500);
+    FPDFPage_InsertObject(page, text_object2);
+  }
+
+  // Generate contents and check that the text renders properly.
+  EXPECT_TRUE(FPDFPage_GenerateContent(page));
+  FPDF_BITMAP page_bitmap = RenderPage(page);
+  const char md5[] = "2bc6c1aaa2252e73246a75775ccf38c2";
+  CompareBitmap(page_bitmap, 612, 792, md5);
+  FPDFBitmap_Destroy(page_bitmap);
+
+  // Save the document, close the page.
+  EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
+  FPDF_ClosePage(page);
+  std::string new_file = GetString();
+
+  // Render the saved result
+  FPDF_FILEACCESS file_access;
+  memset(&file_access, 0, sizeof(file_access));
+  file_access.m_FileLen = new_file.size();
+  file_access.m_GetBlock = GetBlockFromString;
+  file_access.m_Param = &new_file;
+  FPDF_DOCUMENT new_doc = FPDF_LoadCustomDocument(&file_access, nullptr);
+  ASSERT_NE(nullptr, new_doc);
+  EXPECT_EQ(1, FPDF_GetPageCount(new_doc));
+  FPDF_PAGE new_page = FPDF_LoadPage(new_doc, 0);
+  ASSERT_NE(nullptr, new_page);
+  FPDF_BITMAP new_bitmap = RenderPage(new_page);
+  CompareBitmap(new_bitmap, 612, 792, md5);
+  FPDFBitmap_Destroy(new_bitmap);
+  FPDF_ClosePage(new_page);
+  FPDF_CloseDocument(new_doc);
+}
+#endif  // _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_