diff options
Diffstat (limited to 'fpdfsdk')
-rw-r--r-- | fpdfsdk/fpdf_text.cpp | 33 | ||||
-rw-r--r-- | fpdfsdk/fpdf_text_embeddertest.cpp | 83 | ||||
-rw-r--r-- | fpdfsdk/fpdf_view_c_api_test.c | 1 |
3 files changed, 117 insertions, 0 deletions
diff --git a/fpdfsdk/fpdf_text.cpp b/fpdfsdk/fpdf_text.cpp index d8d3b2675b..a39402eb72 100644 --- a/fpdfsdk/fpdf_text.cpp +++ b/fpdfsdk/fpdf_text.cpp @@ -10,7 +10,9 @@ #include <memory> #include <vector> +#include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/page/cpdf_page.h" +#include "core/fpdfapi/page/cpdf_textobject.h" #include "core/fpdfdoc/cpdf_viewerpreferences.h" #include "core/fpdftext/cpdf_linkextract.h" #include "core/fpdftext/cpdf_textpage.h" @@ -88,6 +90,37 @@ FPDF_EXPORT double FPDF_CALLCONV FPDFText_GetFontSize(FPDF_TEXTPAGE text_page, return charinfo.m_FontSize; } +FPDF_EXPORT unsigned long FPDF_CALLCONV +FPDFText_GetFontInfo(FPDF_TEXTPAGE text_page, + int index, + void* buffer, + unsigned long buflen, + int* flags) { + if (!text_page) + return 0; + CPDF_TextPage* pTextObj = CPDFTextPageFromFPDFTextPage(text_page); + + if (index < 0 || index >= pTextObj->CountChars()) + return 0; + + FPDF_CHAR_INFO charinfo; + pTextObj->GetCharInfo(index, &charinfo); + if (!charinfo.m_pTextObj) + return 0; + + CPDF_Font* font = charinfo.m_pTextObj->GetFont(); + if (!font) + return 0; + + if (flags) + *flags = font->GetFontFlags(); + ByteString basefont = font->GetBaseFont(); + unsigned long length = basefont.GetLength() + 1; + if (buffer && buflen >= length) + memcpy(buffer, basefont.c_str(), length); + return length; +} + FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFText_GetCharBox(FPDF_TEXTPAGE text_page, int index, double* left, diff --git a/fpdfsdk/fpdf_text_embeddertest.cpp b/fpdfsdk/fpdf_text_embeddertest.cpp index bf064d672a..83b43d95d0 100644 --- a/fpdfsdk/fpdf_text_embeddertest.cpp +++ b/fpdfsdk/fpdf_text_embeddertest.cpp @@ -8,6 +8,7 @@ #include <vector> #include "core/fxcrt/fx_memory.h" +#include "core/fxge/fx_font.h" #include "public/cpp/fpdf_scopers.h" #include "public/fpdf_text.h" #include "public/fpdf_transformpage.h" @@ -512,6 +513,88 @@ TEST_F(FPDFTextEmbeddertest, GetFontSize) { UnloadPage(page); } +TEST_F(FPDFTextEmbeddertest, GetFontInfo) { + ASSERT_TRUE(OpenDocument("hello_world.pdf")); + FPDF_PAGE page = LoadPage(0); + ASSERT_TRUE(page); + + FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page); + ASSERT_TRUE(textpage); + std::vector<char> font_name; + size_t num_chars1 = strlen("Hello, world!"); + const char kExpectedFontName1[] = "Times-Roman"; + + for (size_t i = 0; i < num_chars1; i++) { + int flags = -1; + unsigned long length = + FPDFText_GetFontInfo(textpage, i, nullptr, 0, &flags); + static constexpr unsigned long expected_length = sizeof(kExpectedFontName1); + ASSERT_EQ(expected_length, length); + EXPECT_EQ(FXFONT_NONSYMBOLIC, flags); + font_name.resize(length); + std::fill(font_name.begin(), font_name.end(), 'a'); + flags = -1; + EXPECT_EQ(expected_length, + FPDFText_GetFontInfo(textpage, i, font_name.data(), + font_name.size(), &flags)); + EXPECT_STREQ(kExpectedFontName1, font_name.data()); + EXPECT_EQ(FXFONT_NONSYMBOLIC, flags); + } + // If the size of the buffer is not large enough, the buffer should remain + // unchanged. + font_name.pop_back(); + std::fill(font_name.begin(), font_name.end(), 'a'); + EXPECT_EQ(sizeof(kExpectedFontName1), + FPDFText_GetFontInfo(textpage, 0, font_name.data(), + font_name.size(), nullptr)); + for (char a : font_name) + EXPECT_EQ('a', a); + + // The text is "Hello, world!\r\nGoodbye, world!", so the next two characters + // do not have any font information. + EXPECT_EQ(0u, FPDFText_GetFontInfo(textpage, num_chars1, font_name.data(), + font_name.size(), nullptr)); + EXPECT_EQ(0u, FPDFText_GetFontInfo(textpage, num_chars1 + 1, font_name.data(), + font_name.size(), nullptr)); + + size_t num_chars2 = strlen("Goodbye, world!"); + const char kExpectedFontName2[] = "Helvetica"; + for (size_t i = num_chars1 + 2; i < num_chars1 + num_chars2 + 2; i++) { + int flags = -1; + unsigned long length = + FPDFText_GetFontInfo(textpage, i, nullptr, 0, &flags); + static constexpr unsigned long expected_length = sizeof(kExpectedFontName2); + ASSERT_EQ(expected_length, length); + EXPECT_EQ(FXFONT_NONSYMBOLIC, flags); + font_name.resize(length); + std::fill(font_name.begin(), font_name.end(), 'a'); + flags = -1; + EXPECT_EQ(expected_length, + FPDFText_GetFontInfo(textpage, i, font_name.data(), + font_name.size(), &flags)); + EXPECT_STREQ(kExpectedFontName2, font_name.data()); + EXPECT_EQ(FXFONT_NONSYMBOLIC, flags); + } + + // Now try some out of bounds indices and null pointers to make sure we do not + // crash. + // No textpage. + EXPECT_EQ(0u, FPDFText_GetFontInfo(nullptr, 0, font_name.data(), + font_name.size(), nullptr)); + // No buffer. + EXPECT_EQ(sizeof(kExpectedFontName1), + FPDFText_GetFontInfo(textpage, 0, nullptr, 0, nullptr)); + // Negative index. + EXPECT_EQ(0u, FPDFText_GetFontInfo(textpage, -1, font_name.data(), + font_name.size(), nullptr)); + // Out of bounds index. + EXPECT_EQ(0u, FPDFText_GetFontInfo(textpage, 1000, font_name.data(), + font_name.size(), nullptr)); + + FPDFText_ClosePage(textpage); + UnloadPage(page); +} + TEST_F(FPDFTextEmbeddertest, ToUnicode) { ASSERT_TRUE(OpenDocument("bug_583.pdf")); FPDF_PAGE page = LoadPage(0); diff --git a/fpdfsdk/fpdf_view_c_api_test.c b/fpdfsdk/fpdf_view_c_api_test.c index d92ae78d65..799956b36a 100644 --- a/fpdfsdk/fpdf_view_c_api_test.c +++ b/fpdfsdk/fpdf_view_c_api_test.c @@ -324,6 +324,7 @@ int CheckPDFiumCApi() { CHK(FPDFText_GetCharBox); CHK(FPDFText_GetCharIndexAtPos); CHK(FPDFText_GetCharOrigin); + CHK(FPDFText_GetFontInfo); CHK(FPDFText_GetFontSize); CHK(FPDFText_GetRect); CHK(FPDFText_GetSchCount); |