From 733e068e077bb59597180bc9b8ff934dd125ffdc Mon Sep 17 00:00:00 2001 From: thestig Date: Wed, 23 Nov 2016 05:52:39 -0800 Subject: Add API for getting page labels. BUG=pdfium:479 Review-Url: https://codereview.chromium.org/2521843003 --- fpdfsdk/fpdfdoc.cpp | 77 ++++++++++++++++++++++++---------------- fpdfsdk/fpdfdoc_embeddertest.cpp | 54 ++++++++++++++++++++++++++++ fpdfsdk/fpdfview_c_api_test.c | 1 + 3 files changed, 102 insertions(+), 30 deletions(-) (limited to 'fpdfsdk') diff --git a/fpdfsdk/fpdfdoc.cpp b/fpdfsdk/fpdfdoc.cpp index 01d91242f4..254be3f883 100644 --- a/fpdfsdk/fpdfdoc.cpp +++ b/fpdfsdk/fpdfdoc.cpp @@ -15,6 +15,7 @@ #include "core/fpdfdoc/cpdf_bookmark.h" #include "core/fpdfdoc/cpdf_bookmarktree.h" #include "core/fpdfdoc/cpdf_dest.h" +#include "core/fpdfdoc/cpdf_pagelabel.h" #include "fpdfsdk/fsdk_define.h" #include "third_party/base/stl_util.h" @@ -58,6 +59,16 @@ CPDF_LinkList* GetLinkList(CPDF_Page* page) { return pHolder->get(); } +unsigned long Utf16EncodeMaybeCopyAndReturnLength(const CFX_WideString& text, + void* buffer, + unsigned long buflen) { + CFX_ByteString encodedText = text.UTF16LE_Encode(); + unsigned long len = encodedText.GetLength(); + if (buffer && buflen >= len) + FXSYS_memcpy(buffer, encodedText.c_str(), len); + return len; +} + } // namespace DLLEXPORT FPDF_BOOKMARK STDCALL @@ -91,12 +102,7 @@ DLLEXPORT unsigned long STDCALL FPDFBookmark_GetTitle(FPDF_BOOKMARK pDict, return 0; CPDF_Bookmark bookmark(ToDictionary(static_cast(pDict))); CFX_WideString title = bookmark.GetTitle(); - CFX_ByteString encodedTitle = title.UTF16LE_Encode(); - unsigned long len = encodedTitle.GetLength(); - if (buffer && buflen >= len) { - FXSYS_memcpy(buffer, encodedTitle.c_str(), len); - } - return len; + return Utf16EncodeMaybeCopyAndReturnLength(title, buffer, buflen); } DLLEXPORT FPDF_BOOKMARK STDCALL FPDFBookmark_Find(FPDF_DOCUMENT document, @@ -354,42 +360,53 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFLink_GetQuadPoints(FPDF_LINK linkAnnot, CPDF_Dictionary* pAnnotDict = ToDictionary(static_cast(linkAnnot)); CPDF_Array* pArray = pAnnotDict->GetArrayFor("QuadPoints"); - if (pArray) { - if (quadIndex < 0 || - static_cast(quadIndex) >= pArray->GetCount() / 8 || - (static_cast(quadIndex * 8 + 7) >= pArray->GetCount())) - return false; - quadPoints->x1 = pArray->GetNumberAt(quadIndex * 8); - quadPoints->y1 = pArray->GetNumberAt(quadIndex * 8 + 1); - quadPoints->x2 = pArray->GetNumberAt(quadIndex * 8 + 2); - quadPoints->y2 = pArray->GetNumberAt(quadIndex * 8 + 3); - quadPoints->x3 = pArray->GetNumberAt(quadIndex * 8 + 4); - quadPoints->y3 = pArray->GetNumberAt(quadIndex * 8 + 5); - quadPoints->x4 = pArray->GetNumberAt(quadIndex * 8 + 6); - quadPoints->y4 = pArray->GetNumberAt(quadIndex * 8 + 7); - return true; + if (!pArray) + return false; + + if (quadIndex < 0 || + static_cast(quadIndex) >= pArray->GetCount() / 8 || + (static_cast(quadIndex * 8 + 7) >= pArray->GetCount())) { + return false; } - return false; + + quadPoints->x1 = pArray->GetNumberAt(quadIndex * 8); + quadPoints->y1 = pArray->GetNumberAt(quadIndex * 8 + 1); + quadPoints->x2 = pArray->GetNumberAt(quadIndex * 8 + 2); + quadPoints->y2 = pArray->GetNumberAt(quadIndex * 8 + 3); + quadPoints->x3 = pArray->GetNumberAt(quadIndex * 8 + 4); + quadPoints->y3 = pArray->GetNumberAt(quadIndex * 8 + 5); + quadPoints->x4 = pArray->GetNumberAt(quadIndex * 8 + 6); + quadPoints->y4 = pArray->GetNumberAt(quadIndex * 8 + 7); + return true; } -DLLEXPORT unsigned long STDCALL FPDF_GetMetaText(FPDF_DOCUMENT doc, +DLLEXPORT unsigned long STDCALL FPDF_GetMetaText(FPDF_DOCUMENT document, FPDF_BYTESTRING tag, void* buffer, unsigned long buflen) { if (!tag) return 0; - CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(doc); + CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return 0; CPDF_Dictionary* pInfo = pDoc->GetInfo(); if (!pInfo) return 0; CFX_WideString text = pInfo->GetUnicodeTextFor(tag); - // Use UTF-16LE encoding - CFX_ByteString encodedText = text.UTF16LE_Encode(); - unsigned long len = encodedText.GetLength(); - if (buffer && buflen >= len) { - FXSYS_memcpy(buffer, encodedText.c_str(), len); - } - return len; + return Utf16EncodeMaybeCopyAndReturnLength(text, buffer, buflen); +} + +DLLEXPORT unsigned long STDCALL FPDF_GetPagelLabel(FPDF_DOCUMENT document, + int page_index, + void* buffer, + unsigned long buflen) { + if (page_index < 0) + return 0; + + // CPDF_PageLabel can deal with NULL |document|. + CPDF_PageLabel label(CPDFDocumentFromFPDFDocument(document)); + CFX_WideString str; + if (!label.GetLabel(page_index, &str)) + return 0; + return Utf16EncodeMaybeCopyAndReturnLength(str, buffer, buflen); } diff --git a/fpdfsdk/fpdfdoc_embeddertest.cpp b/fpdfsdk/fpdfdoc_embeddertest.cpp index d7f1f97117..67934c5626 100644 --- a/fpdfsdk/fpdfdoc_embeddertest.cpp +++ b/fpdfsdk/fpdfdoc_embeddertest.cpp @@ -172,3 +172,57 @@ TEST_F(FPDFDocEmbeddertest, DeletePage) { FPDFPage_Delete(document(), 0); EXPECT_EQ(0, FPDF_GetPageCount(document())); } + +TEST_F(FPDFDocEmbeddertest, NoPageLabels) { + EXPECT_TRUE(OpenDocument("about_blank.pdf")); + EXPECT_EQ(1, FPDF_GetPageCount(document())); + + ASSERT_EQ(0u, FPDF_GetPagelLabel(document(), 0, nullptr, 0)); +} + +TEST_F(FPDFDocEmbeddertest, GetPageLabels) { + EXPECT_TRUE(OpenDocument("page_labels.pdf")); + EXPECT_EQ(7, FPDF_GetPageCount(document())); + + unsigned short buf[128]; + EXPECT_EQ(0u, FPDF_GetPagelLabel(document(), -2, buf, sizeof(buf))); + EXPECT_EQ(0u, FPDF_GetPagelLabel(document(), -1, buf, sizeof(buf))); + + const FX_WCHAR kExpectedPageLabel0[] = L"i"; + ASSERT_EQ(4u, FPDF_GetPagelLabel(document(), 0, buf, sizeof(buf))); + EXPECT_EQ(CFX_WideString(kExpectedPageLabel0), + CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel0))); + + const FX_WCHAR kExpectedPageLabel1[] = L"ii"; + ASSERT_EQ(6u, FPDF_GetPagelLabel(document(), 1, buf, sizeof(buf))); + EXPECT_EQ(CFX_WideString(kExpectedPageLabel1), + CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel1))); + + const FX_WCHAR kExpectedPageLabel2[] = L"1"; + ASSERT_EQ(4u, FPDF_GetPagelLabel(document(), 2, buf, sizeof(buf))); + EXPECT_EQ(CFX_WideString(kExpectedPageLabel2), + CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel2))); + + const FX_WCHAR kExpectedPageLabel3[] = L"2"; + ASSERT_EQ(4u, FPDF_GetPagelLabel(document(), 3, buf, sizeof(buf))); + EXPECT_EQ(CFX_WideString(kExpectedPageLabel3), + CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel3))); + + const FX_WCHAR kExpectedPageLabel4[] = L"zzA"; + ASSERT_EQ(8u, FPDF_GetPagelLabel(document(), 4, buf, sizeof(buf))); + EXPECT_EQ(CFX_WideString(kExpectedPageLabel4), + CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel4))); + + const FX_WCHAR kExpectedPageLabel5[] = L"zzB"; + ASSERT_EQ(8u, FPDF_GetPagelLabel(document(), 5, buf, sizeof(buf))); + EXPECT_EQ(CFX_WideString(kExpectedPageLabel5), + CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel5))); + + const FX_WCHAR kExpectedPageLabel6[] = L""; + ASSERT_EQ(2u, FPDF_GetPagelLabel(document(), 6, buf, sizeof(buf))); + EXPECT_EQ(CFX_WideString(kExpectedPageLabel6), + CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel6))); + + ASSERT_EQ(0u, FPDF_GetPagelLabel(document(), 7, buf, sizeof(buf))); + ASSERT_EQ(0u, FPDF_GetPagelLabel(document(), 8, buf, sizeof(buf))); +} diff --git a/fpdfsdk/fpdfview_c_api_test.c b/fpdfsdk/fpdfview_c_api_test.c index afc357f1e3..5e6c36f2b1 100644 --- a/fpdfsdk/fpdfview_c_api_test.c +++ b/fpdfsdk/fpdfview_c_api_test.c @@ -64,6 +64,7 @@ int CheckPDFiumCApi() { CHK(FPDFLink_CountQuadPoints); CHK(FPDFLink_GetQuadPoints); CHK(FPDF_GetMetaText); + CHK(FPDF_GetPagelLabel); // fpdf_edit.h CHK(FPDF_CreateNewDocument); -- cgit v1.2.3