summaryrefslogtreecommitdiff
path: root/fpdfsdk
diff options
context:
space:
mode:
authorHenrique Nakashima <hnakashima@chromium.org>2018-01-10 18:06:55 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-01-10 18:06:55 +0000
commita74e75d69594e469906e2a95b5f2394c88acbe7a (patch)
tree3c77b9358876819d50baa7f43a98e15dd33c2bbf /fpdfsdk
parent7d36c3e835bc32898f0064226d79a8f0f89e15ec (diff)
downloadpdfium-a74e75d69594e469906e2a95b5f2394c88acbe7a.tar.xz
Add FPDFAnnot_GetAP to public API.
The matching FPDFAnnot_SetAP will be added in a subsequent CL. Change-Id: If567e02c6c56138d218498879cb4a8ee91dff080 Reviewed-on: https://pdfium-review.googlesource.com/22450 Reviewed-by: dsinclair <dsinclair@chromium.org> Commit-Queue: Henrique Nakashima <hnakashima@chromium.org>
Diffstat (limited to 'fpdfsdk')
-rw-r--r--fpdfsdk/fpdfannot.cpp39
-rw-r--r--fpdfsdk/fpdfannot_embeddertest.cpp91
-rw-r--r--fpdfsdk/fpdfview_c_api_test.c1
3 files changed, 114 insertions, 17 deletions
diff --git a/fpdfsdk/fpdfannot.cpp b/fpdfsdk/fpdfannot.cpp
index ec541f55d0..c7433d03d8 100644
--- a/fpdfsdk/fpdfannot.cpp
+++ b/fpdfsdk/fpdfannot.cpp
@@ -104,6 +104,18 @@ static_assert(static_cast<int>(CPDF_Annot::Subtype::XFAWIDGET) ==
FPDF_ANNOT_XFAWIDGET,
"CPDF_Annot::XFAWIDGET value mismatch");
+// These checks ensure the consistency of annotation appearance mode values
+// across core/ and public.
+static_assert(static_cast<int>(CPDF_Annot::AppearanceMode::Normal) ==
+ FPDF_ANNOT_APPEARANCEMODE_NORMAL,
+ "CPDF_Annot::AppearanceMode::Normal value mismatch");
+static_assert(static_cast<int>(CPDF_Annot::AppearanceMode::Rollover) ==
+ FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
+ "CPDF_Annot::AppearanceMode::Rollover value mismatch");
+static_assert(static_cast<int>(CPDF_Annot::AppearanceMode::Down) ==
+ FPDF_ANNOT_APPEARANCEMODE_DOWN,
+ "CPDF_Annot::AppearanceMode::Down value mismatch");
+
// These checks ensure the consistency of dictionary value types across core/
// and public/.
static_assert(static_cast<int>(CPDF_Object::Type::BOOLEAN) ==
@@ -735,6 +747,33 @@ FPDFAnnot_GetStringValue(FPDF_ANNOTATION annot,
buffer, buflen);
}
+FPDF_EXPORT unsigned long FPDF_CALLCONV
+FPDFAnnot_GetAP(FPDF_ANNOTATION annot,
+ FPDF_ANNOT_APPEARANCEMODE appearanceMode,
+ void* buffer,
+ unsigned long buflen) {
+ if (appearanceMode < 0 || appearanceMode >= FPDF_ANNOT_APPEARANCEMODE_COUNT)
+ return 0;
+
+ if (!annot)
+ return 0;
+
+ CPDF_Dictionary* pAnnotDict =
+ CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict();
+ if (!pAnnotDict)
+ return 0;
+
+ CPDF_Annot::AppearanceMode mode =
+ static_cast<CPDF_Annot::AppearanceMode>(appearanceMode);
+
+ CPDF_Stream* pStream = FPDFDOC_GetAnnotAPNoFallback(pAnnotDict, mode);
+ if (!pStream)
+ return Utf16EncodeMaybeCopyAndReturnLength(L"", buffer, buflen);
+
+ return Utf16EncodeMaybeCopyAndReturnLength(pStream->GetUnicodeText(), buffer,
+ buflen);
+}
+
FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV
FPDFAnnot_GetLinkedAnnot(FPDF_ANNOTATION annot, FPDF_BYTESTRING key) {
CPDF_AnnotContext* pAnnot = CPDFAnnotContextFromFPDFAnnotation(annot);
diff --git a/fpdfsdk/fpdfannot_embeddertest.cpp b/fpdfsdk/fpdfannot_embeddertest.cpp
index dce658201c..6d4521f26e 100644
--- a/fpdfsdk/fpdfannot_embeddertest.cpp
+++ b/fpdfsdk/fpdfannot_embeddertest.cpp
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <cwchar>
#include <memory>
#include <string>
#include <vector>
@@ -11,12 +12,21 @@
#include "public/fpdf_edit.h"
#include "public/fpdfview.h"
#include "testing/embedder_test.h"
+#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gtest/include/gtest/gtest.h"
static constexpr char kContentsKey[] = "Contents";
class FPDFAnnotEmbeddertest : public EmbedderTest {};
+const std::wstring BufferToWString(std::vector<char>& buf) {
+ return GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()));
+}
+
+const std::string BufferToString(std::vector<char>& buf) {
+ return GetPlatformString(reinterpret_cast<unsigned short*>(buf.data()));
+}
+
TEST_F(FPDFAnnotEmbeddertest, RenderAnnotWithOnlyRolloverAP) {
// Open a file with one annotation and load its first page.
ASSERT_TRUE(OpenDocument("annotation_highlight_rollover_ap.pdf"));
@@ -66,9 +76,7 @@ TEST_F(FPDFAnnotEmbeddertest, ExtractHighlightLongContent) {
unsigned long len = FPDFAnnot_GetStringValue(annot, kAuthorKey, nullptr, 0);
std::vector<char> buf(len);
EXPECT_EQ(28u, FPDFAnnot_GetStringValue(annot, kAuthorKey, buf.data(), len));
- EXPECT_STREQ(L"Jae Hyun Park",
- GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
- .c_str());
+ EXPECT_STREQ(L"Jae Hyun Park", BufferToWString(buf).c_str());
// Check that the content is correct.
EXPECT_EQ(FPDF_OBJECT_STRING, FPDFAnnot_GetValueType(annot, kContentsKey));
@@ -98,9 +106,7 @@ TEST_F(FPDFAnnotEmbeddertest, ExtractHighlightLongContent) {
"longLong long longLong long longLong long longLong long longLong long "
"longLong long longLong long longLong long longLong long longLong long "
"longLong long long. END";
- EXPECT_STREQ(contents,
- GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
- .c_str());
+ EXPECT_STREQ(contents, BufferToWString(buf).c_str());
// Check that the quadpoints are correct.
FS_QUADPOINTSF quadpoints;
@@ -243,9 +249,7 @@ TEST_F(FPDFAnnotEmbeddertest, AddFirstTextAnnotation) {
std::vector<char> buf(len);
EXPECT_EQ(74u,
FPDFAnnot_GetStringValue(annot, kContentsKey, buf.data(), len));
- EXPECT_STREQ(contents,
- GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
- .c_str());
+ EXPECT_STREQ(contents, BufferToWString(buf).c_str());
FPDFPage_CloseAnnot(annot);
UnloadPage(page);
@@ -838,8 +842,7 @@ TEST_F(FPDFAnnotEmbeddertest, GetSetStringValue) {
std::vector<char> buf(len);
EXPECT_EQ(66u, FPDFAnnot_GetStringValue(annot, kHashKey, buf.data(), len));
EXPECT_STREQ(L"395fbcb98d558681742f30683a62a2ad",
- GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
- .c_str());
+ BufferToWString(buf).c_str());
// Check that the string value of the modified date is correct.
static constexpr char kDateKey[] = "M";
@@ -848,9 +851,7 @@ TEST_F(FPDFAnnotEmbeddertest, GetSetStringValue) {
buf.clear();
buf.resize(len);
EXPECT_EQ(44u, FPDFAnnot_GetStringValue(annot, kDateKey, buf.data(), len));
- EXPECT_STREQ(L"D:201706071721Z00'00'",
- GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
- .c_str());
+ EXPECT_STREQ(L"D:201706071721Z00'00'", BufferToWString(buf).c_str());
// Update the date entry for the annotation.
const wchar_t new_date[] = L"D:201706282359Z00'00'";
@@ -881,15 +882,71 @@ TEST_F(FPDFAnnotEmbeddertest, GetSetStringValue) {
buf.resize(len);
EXPECT_EQ(44u,
FPDFAnnot_GetStringValue(new_annot, kDateKey, buf.data(), len));
- EXPECT_STREQ(new_date,
- GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
- .c_str());
+ EXPECT_STREQ(new_date, BufferToWString(buf).c_str());
FPDFPage_CloseAnnot(new_annot);
CloseSavedPage(page);
CloseSavedDocument();
}
+TEST_F(FPDFAnnotEmbeddertest, GetAP) {
+ // Open a file with four annotations and load its first page.
+ ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
+ FPDF_PAGE page = FPDF_LoadPage(document(), 0);
+ ASSERT_TRUE(page);
+
+ // Retrieve the first annotation.
+ FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 0);
+ ASSERT_TRUE(annot);
+
+ // Check that the string value of an AP returns the expected length.
+ unsigned long len =
+ FPDFAnnot_GetAP(annot, FPDF_ANNOT_APPEARANCEMODE_NORMAL, nullptr, 0);
+ EXPECT_EQ(73970u, len);
+
+ // Check that the string value of an AP is not returned if the buffer is too
+ // small. The result buffer should be overwritten with an empty string.
+ std::vector<char> buf(len - 1);
+ // Write L"z" in the buffer to verify it's not overwritten.
+ wcscpy(reinterpret_cast<wchar_t*>(buf.data()), L"z");
+ EXPECT_EQ(73970u, FPDFAnnot_GetAP(annot, FPDF_ANNOT_APPEARANCEMODE_NORMAL,
+ buf.data(), len - 1));
+ std::string ap = BufferToString(buf);
+ EXPECT_STREQ("z", ap.c_str());
+
+ // Check that the string value of an AP is returned through a buffer that is
+ // the right size.
+ buf.clear();
+ buf.resize(len);
+ EXPECT_EQ(73970u, FPDFAnnot_GetAP(annot, FPDF_ANNOT_APPEARANCEMODE_NORMAL,
+ buf.data(), len));
+ ap = BufferToString(buf);
+ EXPECT_THAT(ap, testing::StartsWith("q Q q 7.442786 w 2 J"));
+ EXPECT_THAT(ap, testing::EndsWith("c 716.5381 327.7156 l S Q Q"));
+
+ // Check that the string value of an AP is returned through a buffer that is
+ // larger than necessary.
+ buf.clear();
+ buf.resize(len + 1);
+ EXPECT_EQ(73970u, FPDFAnnot_GetAP(annot, FPDF_ANNOT_APPEARANCEMODE_NORMAL,
+ buf.data(), len + 1));
+ ap = BufferToString(buf);
+ EXPECT_THAT(ap, testing::StartsWith("q Q q 7.442786 w 2 J"));
+ EXPECT_THAT(ap, testing::EndsWith("c 716.5381 327.7156 l S Q Q"));
+
+ // Check that getting an AP for a mode that does not have an AP returns an
+ // empty string.
+ buf.clear();
+ buf.resize(len);
+ EXPECT_EQ(2u, FPDFAnnot_GetAP(annot, FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
+ buf.data(), len));
+ ap = BufferToString(buf);
+ EXPECT_STREQ("", ap.c_str());
+
+ FPDFPage_CloseAnnot(annot);
+ FPDF_ClosePage(page);
+}
+
TEST_F(FPDFAnnotEmbeddertest, ExtractLinkedAnnotations) {
// Open a file with annotations and load its first page.
ASSERT_TRUE(OpenDocument("annotation_highlight_square_with_ap.pdf"));
diff --git a/fpdfsdk/fpdfview_c_api_test.c b/fpdfsdk/fpdfview_c_api_test.c
index 5f935fc665..08696c2e27 100644
--- a/fpdfsdk/fpdfview_c_api_test.c
+++ b/fpdfsdk/fpdfview_c_api_test.c
@@ -62,6 +62,7 @@ int CheckPDFiumCApi() {
CHK(FPDFAnnot_GetValueType);
CHK(FPDFAnnot_SetStringValue);
CHK(FPDFAnnot_GetStringValue);
+ CHK(FPDFAnnot_GetAP);
CHK(FPDFAnnot_GetLinkedAnnot);
CHK(FPDFAnnot_GetFlags);
CHK(FPDFAnnot_SetFlags);