blob: db5b3c26daefea4984c7b664c714421ab655b3b9 [file] [log] [blame]
Jane Liu4fd9a472017-06-01 18:56:09 -04001// Copyright 2017 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00005#include <algorithm>
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00006#include <cwchar>
Jane Liu20eafda2017-06-07 10:33:24 -04007#include <memory>
8#include <string>
Jane Liu4fd9a472017-06-01 18:56:09 -04009#include <vector>
10
Lei Zhange4cdac52019-04-30 16:45:57 +000011#include "build/build_config.h"
Lei Zhanga5c1daf2019-01-31 21:56:47 +000012#include "constants/annotation_common.h"
Jane Liubaa7ff42017-06-29 19:18:23 -040013#include "core/fxcrt/fx_system.h"
Tom Sepeze08d2b12018-04-25 18:49:32 +000014#include "public/cpp/fpdf_scopers.h"
Jane Liu4fd9a472017-06-01 18:56:09 -040015#include "public/fpdf_annot.h"
Jane Liubaa7ff42017-06-29 19:18:23 -040016#include "public/fpdf_edit.h"
Jane Liu4fd9a472017-06-01 18:56:09 -040017#include "public/fpdfview.h"
18#include "testing/embedder_test.h"
Lei Zhangb6992dd2019-02-05 23:30:20 +000019#include "testing/fx_string_testhelpers.h"
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +000020#include "testing/gmock/include/gmock/gmock-matchers.h"
Jane Liu4fd9a472017-06-01 18:56:09 -040021#include "testing/gtest/include/gtest/gtest.h"
Lei Zhang5bf8c7f2019-04-08 17:50:11 +000022#include "testing/utils/hash.h"
Jane Liu4fd9a472017-06-01 18:56:09 -040023
Lei Zhangab41f252018-12-23 03:10:50 +000024class FPDFAnnotEmbedderTest : public EmbedderTest {};
Jane Liu4fd9a472017-06-01 18:56:09 -040025
Lei Zhangab41f252018-12-23 03:10:50 +000026TEST_F(FPDFAnnotEmbedderTest, BadParams) {
Lei Zhang7557e7b2018-09-14 17:02:40 +000027 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
28 FPDF_PAGE page = LoadPage(0);
29 ASSERT_TRUE(page);
30
31 EXPECT_EQ(0, FPDFPage_GetAnnotCount(nullptr));
32
33 EXPECT_FALSE(FPDFPage_GetAnnot(nullptr, 0));
34 EXPECT_FALSE(FPDFPage_GetAnnot(nullptr, -1));
35 EXPECT_FALSE(FPDFPage_GetAnnot(nullptr, 1));
36 EXPECT_FALSE(FPDFPage_GetAnnot(page, -1));
37 EXPECT_FALSE(FPDFPage_GetAnnot(page, 1));
38
39 EXPECT_EQ(FPDF_ANNOT_UNKNOWN, FPDFAnnot_GetSubtype(nullptr));
40
41 EXPECT_EQ(0, FPDFAnnot_GetObjectCount(nullptr));
42
43 EXPECT_FALSE(FPDFAnnot_GetObject(nullptr, 0));
44 EXPECT_FALSE(FPDFAnnot_GetObject(nullptr, -1));
45 EXPECT_FALSE(FPDFAnnot_GetObject(nullptr, 1));
46
47 EXPECT_FALSE(FPDFAnnot_HasKey(nullptr, "foo"));
48
Lei Zhang4f556b82019-04-08 16:32:41 +000049 static const wchar_t kContents[] = L"Bar";
Lei Zhangf0f67682019-04-08 17:03:21 +000050 ScopedFPDFWideString text = GetFPDFWideString(kContents);
Lei Zhang7557e7b2018-09-14 17:02:40 +000051 EXPECT_FALSE(FPDFAnnot_SetStringValue(nullptr, "foo", text.get()));
52
Lei Zhang5bf8c7f2019-04-08 17:50:11 +000053 FPDF_WCHAR buffer[64];
Lei Zhang7557e7b2018-09-14 17:02:40 +000054 EXPECT_EQ(0u, FPDFAnnot_GetStringValue(nullptr, "foo", nullptr, 0));
55 EXPECT_EQ(0u, FPDFAnnot_GetStringValue(nullptr, "foo", buffer, 0));
56 EXPECT_EQ(0u,
57 FPDFAnnot_GetStringValue(nullptr, "foo", buffer, sizeof(buffer)));
58
59 UnloadPage(page);
60}
61
Lei Zhang3d9a0972019-03-04 19:34:09 +000062TEST_F(FPDFAnnotEmbedderTest, BadAnnotsEntry) {
63 ASSERT_TRUE(OpenDocument("bad_annots_entry.pdf"));
64 FPDF_PAGE page = LoadPage(0);
65 ASSERT_TRUE(page);
66
67 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
Lei Zhang98dc8c02019-03-04 19:40:30 +000068 EXPECT_FALSE(FPDFPage_GetAnnot(page, 0));
Lei Zhang3d9a0972019-03-04 19:34:09 +000069
70 UnloadPage(page);
71}
72
Lei Zhangab41f252018-12-23 03:10:50 +000073TEST_F(FPDFAnnotEmbedderTest, RenderAnnotWithOnlyRolloverAP) {
Jane Liue17011d2017-06-21 12:18:37 -040074 // Open a file with one annotation and load its first page.
75 ASSERT_TRUE(OpenDocument("annotation_highlight_rollover_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +000076 FPDF_PAGE page = LoadPage(0);
Jane Liue17011d2017-06-21 12:18:37 -040077 ASSERT_TRUE(page);
78
79 // This annotation has a malformed appearance stream, which does not have its
80 // normal appearance defined, only its rollover appearance. In this case, its
81 // normal appearance should be generated, allowing the highlight annotation to
82 // still display.
Tom Sepeze08d2b12018-04-25 18:49:32 +000083 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhanga98e3662018-02-07 20:28:35 +000084 CompareBitmap(bitmap.get(), 612, 792, "dc98f06da047bd8aabfa99562d2cbd1e");
Jane Liue17011d2017-06-21 12:18:37 -040085
86 UnloadPage(page);
87}
88
Lei Zhang03e5e682019-09-16 19:45:55 +000089// TODO(crbug.com/pdfium/11): Fix this test and enable.
90#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
91#define MAYBE_RenderMultilineMarkupAnnotWithoutAP \
92 DISABLED_RenderMultilineMarkupAnnotWithoutAP
93#else
94#define MAYBE_RenderMultilineMarkupAnnotWithoutAP \
95 RenderMultilineMarkupAnnotWithoutAP
96#endif
97TEST_F(FPDFAnnotEmbedderTest, MAYBE_RenderMultilineMarkupAnnotWithoutAP) {
Lei Zhang4f556b82019-04-08 16:32:41 +000098 static const char kMd5[] = "76512832d88017668d9acc7aacd13dae";
Henrique Nakashima5098b252018-03-26 21:46:00 +000099 // Open a file with multiline markup annotations.
Ralf Sipplb3a52402018-03-19 23:30:28 +0000100 ASSERT_TRUE(OpenDocument("annotation_markup_multiline_no_ap.pdf"));
101 FPDF_PAGE page = LoadPage(0);
102 ASSERT_TRUE(page);
103
Tom Sepeze08d2b12018-04-25 18:49:32 +0000104 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000105 CompareBitmap(bitmap.get(), 595, 842, kMd5);
Ralf Sipplb3a52402018-03-19 23:30:28 +0000106
107 UnloadPage(page);
108}
109
Lei Zhangab41f252018-12-23 03:10:50 +0000110TEST_F(FPDFAnnotEmbedderTest, ExtractHighlightLongContent) {
Jane Liu4fd9a472017-06-01 18:56:09 -0400111 // Open a file with one annotation and load its first page.
112 ASSERT_TRUE(OpenDocument("annotation_highlight_long_content.pdf"));
Tom Sepez507d0192018-11-07 16:37:51 +0000113 FPDF_PAGE page = LoadPageNoEvents(0);
Jane Liu4fd9a472017-06-01 18:56:09 -0400114 ASSERT_TRUE(page);
115
116 // Check that there is a total of 1 annotation on its first page.
117 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
118
119 // Check that the annotation is of type "highlight".
Lei Zhanga21d5932018-02-05 18:28:38 +0000120 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000121 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000122 ASSERT_TRUE(annot);
123 EXPECT_EQ(FPDF_ANNOT_HIGHLIGHT, FPDFAnnot_GetSubtype(annot.get()));
Jane Liu4fd9a472017-06-01 18:56:09 -0400124
Lei Zhanga21d5932018-02-05 18:28:38 +0000125 // Check that the annotation color is yellow.
126 unsigned int R;
127 unsigned int G;
128 unsigned int B;
129 unsigned int A;
Lei Zhang75c81712018-02-08 17:22:39 +0000130 ASSERT_TRUE(FPDFAnnot_GetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, &R,
Lei Zhanga21d5932018-02-05 18:28:38 +0000131 &G, &B, &A));
132 EXPECT_EQ(255u, R);
133 EXPECT_EQ(255u, G);
134 EXPECT_EQ(0u, B);
135 EXPECT_EQ(255u, A);
Jane Liu4fd9a472017-06-01 18:56:09 -0400136
Lei Zhanga21d5932018-02-05 18:28:38 +0000137 // Check that the author is correct.
Lei Zhang4f556b82019-04-08 16:32:41 +0000138 static const char kAuthorKey[] = "T";
Lei Zhanga21d5932018-02-05 18:28:38 +0000139 EXPECT_EQ(FPDF_OBJECT_STRING,
140 FPDFAnnot_GetValueType(annot.get(), kAuthorKey));
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000141 unsigned long length_bytes =
Lei Zhanga21d5932018-02-05 18:28:38 +0000142 FPDFAnnot_GetStringValue(annot.get(), kAuthorKey, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000143 ASSERT_EQ(28u, length_bytes);
144 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
Lei Zhanga21d5932018-02-05 18:28:38 +0000145 EXPECT_EQ(28u, FPDFAnnot_GetStringValue(annot.get(), kAuthorKey, buf.data(),
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000146 length_bytes));
147 EXPECT_EQ(L"Jae Hyun Park", GetPlatformWString(buf.data()));
Jane Liu4fd9a472017-06-01 18:56:09 -0400148
Lei Zhanga21d5932018-02-05 18:28:38 +0000149 // Check that the content is correct.
Lei Zhanga5c1daf2019-01-31 21:56:47 +0000150 EXPECT_EQ(
151 FPDF_OBJECT_STRING,
152 FPDFAnnot_GetValueType(annot.get(), pdfium::annotation::kContents));
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000153 length_bytes = FPDFAnnot_GetStringValue(
154 annot.get(), pdfium::annotation::kContents, nullptr, 0);
155 ASSERT_EQ(2690u, length_bytes);
156 buf = GetFPDFWideStringBuffer(length_bytes);
157 EXPECT_EQ(2690u, FPDFAnnot_GetStringValue(annot.get(),
158 pdfium::annotation::kContents,
159 buf.data(), length_bytes));
Lei Zhang4f556b82019-04-08 16:32:41 +0000160 static const wchar_t kContents[] =
Lei Zhanga21d5932018-02-05 18:28:38 +0000161 L"This is a note for that highlight annotation. Very long highlight "
162 "annotation. Long long long Long long longLong long longLong long "
163 "longLong long longLong long longLong long longLong long longLong long "
164 "longLong long longLong long longLong long longLong long longLong long "
165 "longLong long longLong long longLong long longLong long longLong long "
166 "longLong long longLong long longLong long longLong long longLong long "
167 "longLong long longLong long longLong long longLong long longLong long "
168 "longLong long longLong long longLong long longLong long longLong long "
169 "longLong long longLong long longLong long longLong long longLong long "
170 "longLong long longLong long longLong long longLong long longLong long "
171 "longLong long longLong long longLong long longLong long longLong long "
172 "longLong long longLong long longLong long longLong long longLong long "
173 "longLong long longLong long longLong long longLong long longLong long "
174 "longLong long longLong long longLong long longLong long longLong long "
175 "longLong long longLong long longLong long longLong long longLong long "
176 "longLong long longLong long longLong long longLong long longLong long "
177 "longLong long longLong long longLong long longLong long longLong long "
178 "longLong long longLong long longLong long longLong long longLong long "
179 "longLong long longLong long longLong long longLong long longLong long "
180 "longLong long long. END";
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000181 EXPECT_EQ(kContents, GetPlatformWString(buf.data()));
Jane Liu4fd9a472017-06-01 18:56:09 -0400182
Lei Zhanga21d5932018-02-05 18:28:38 +0000183 // Check that the quadpoints are correct.
184 FS_QUADPOINTSF quadpoints;
Ralf Sippl16381792018-04-12 21:20:26 +0000185 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot.get(), 0, &quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000186 EXPECT_EQ(115.802643f, quadpoints.x1);
187 EXPECT_EQ(718.913940f, quadpoints.y1);
188 EXPECT_EQ(157.211182f, quadpoints.x4);
189 EXPECT_EQ(706.264465f, quadpoints.y4);
190 }
Tom Sepez507d0192018-11-07 16:37:51 +0000191 UnloadPageNoEvents(page);
Jane Liu4fd9a472017-06-01 18:56:09 -0400192}
193
Lei Zhang03e5e682019-09-16 19:45:55 +0000194// TODO(crbug.com/pdfium/11): Fix this test and enable.
195#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
196#define MAYBE_ExtractInkMultiple DISABLED_ExtractInkMultiple
197#else
198#define MAYBE_ExtractInkMultiple ExtractInkMultiple
199#endif
200TEST_F(FPDFAnnotEmbedderTest, MAYBE_ExtractInkMultiple) {
Jane Liu4fd9a472017-06-01 18:56:09 -0400201 // Open a file with three annotations and load its first page.
202 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
Tom Sepez507d0192018-11-07 16:37:51 +0000203 FPDF_PAGE page = LoadPageNoEvents(0);
Jane Liu4fd9a472017-06-01 18:56:09 -0400204 ASSERT_TRUE(page);
205
206 // Check that there is a total of 3 annotation on its first page.
207 EXPECT_EQ(3, FPDFPage_GetAnnotCount(page));
208
Lei Zhanga21d5932018-02-05 18:28:38 +0000209 {
210 // Check that the third annotation is of type "ink".
Tom Sepeze08d2b12018-04-25 18:49:32 +0000211 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +0000212 ASSERT_TRUE(annot);
213 EXPECT_EQ(FPDF_ANNOT_INK, FPDFAnnot_GetSubtype(annot.get()));
Jane Liu4fd9a472017-06-01 18:56:09 -0400214
Lei Zhanga21d5932018-02-05 18:28:38 +0000215 // Check that the annotation color is blue with opacity.
216 unsigned int R;
217 unsigned int G;
218 unsigned int B;
219 unsigned int A;
Lei Zhang75c81712018-02-08 17:22:39 +0000220 ASSERT_TRUE(FPDFAnnot_GetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, &R,
Lei Zhanga21d5932018-02-05 18:28:38 +0000221 &G, &B, &A));
222 EXPECT_EQ(0u, R);
223 EXPECT_EQ(0u, G);
224 EXPECT_EQ(255u, B);
225 EXPECT_EQ(76u, A);
Jane Liu4fd9a472017-06-01 18:56:09 -0400226
Lei Zhanga21d5932018-02-05 18:28:38 +0000227 // Check that there is no content.
Lei Zhanga5c1daf2019-01-31 21:56:47 +0000228 EXPECT_EQ(2u, FPDFAnnot_GetStringValue(
229 annot.get(), pdfium::annotation::kContents, nullptr, 0));
Jane Liu4fd9a472017-06-01 18:56:09 -0400230
Lei Zhang4f556b82019-04-08 16:32:41 +0000231 // Check that the rectangle coordinates are correct.
Lei Zhanga21d5932018-02-05 18:28:38 +0000232 // Note that upon rendering, the rectangle coordinates will be adjusted.
233 FS_RECTF rect;
234 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
235 EXPECT_EQ(351.820404f, rect.left);
236 EXPECT_EQ(583.830688f, rect.bottom);
237 EXPECT_EQ(475.336090f, rect.right);
238 EXPECT_EQ(681.535034f, rect.top);
239 }
Tom Sepezef43c262018-11-07 16:41:32 +0000240 {
241 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
242 CompareBitmap(bitmap.get(), 612, 792, "354002e1c4386d38fdde29ef8d61074a");
243 }
Tom Sepez507d0192018-11-07 16:37:51 +0000244 UnloadPageNoEvents(page);
Jane Liu4fd9a472017-06-01 18:56:09 -0400245}
Jane Liu20eafda2017-06-07 10:33:24 -0400246
Lei Zhangab41f252018-12-23 03:10:50 +0000247TEST_F(FPDFAnnotEmbedderTest, AddIllegalSubtypeAnnotation) {
Jane Liu20eafda2017-06-07 10:33:24 -0400248 // Open a file with one annotation and load its first page.
249 ASSERT_TRUE(OpenDocument("annotation_highlight_long_content.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000250 FPDF_PAGE page = LoadPage(0);
Jane Liu20eafda2017-06-07 10:33:24 -0400251 ASSERT_TRUE(page);
252
253 // Add an annotation with an illegal subtype.
Jane Liud60e9ad2017-06-26 11:28:36 -0400254 ASSERT_FALSE(FPDFPage_CreateAnnot(page, -1));
Jane Liu20eafda2017-06-07 10:33:24 -0400255
256 UnloadPage(page);
257}
258
Lei Zhangab41f252018-12-23 03:10:50 +0000259TEST_F(FPDFAnnotEmbedderTest, AddFirstTextAnnotation) {
Jane Liu20eafda2017-06-07 10:33:24 -0400260 // Open a file with no annotation and load its first page.
261 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000262 FPDF_PAGE page = LoadPage(0);
Jane Liu20eafda2017-06-07 10:33:24 -0400263 ASSERT_TRUE(page);
264 EXPECT_EQ(0, FPDFPage_GetAnnotCount(page));
265
Lei Zhanga21d5932018-02-05 18:28:38 +0000266 {
267 // Add a text annotation to the page.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000268 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_TEXT));
Lei Zhanga21d5932018-02-05 18:28:38 +0000269 ASSERT_TRUE(annot);
Jane Liu20eafda2017-06-07 10:33:24 -0400270
Lei Zhanga21d5932018-02-05 18:28:38 +0000271 // Check that there is now 1 annotations on this page.
272 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
Jane Liu20eafda2017-06-07 10:33:24 -0400273
Lei Zhanga21d5932018-02-05 18:28:38 +0000274 // Check that the subtype of the annotation is correct.
275 EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
276 }
Jane Liue10509a2017-06-20 16:47:41 -0400277
Lei Zhanga21d5932018-02-05 18:28:38 +0000278 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000279 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000280 ASSERT_TRUE(annot);
281 EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
Jane Liu20eafda2017-06-07 10:33:24 -0400282
Lei Zhanga21d5932018-02-05 18:28:38 +0000283 // Set the color of the annotation.
284 ASSERT_TRUE(FPDFAnnot_SetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, 51,
285 102, 153, 204));
286 // Check that the color has been set correctly.
287 unsigned int R;
288 unsigned int G;
289 unsigned int B;
290 unsigned int A;
Lei Zhang75c81712018-02-08 17:22:39 +0000291 ASSERT_TRUE(FPDFAnnot_GetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, &R,
Lei Zhanga21d5932018-02-05 18:28:38 +0000292 &G, &B, &A));
293 EXPECT_EQ(51u, R);
294 EXPECT_EQ(102u, G);
295 EXPECT_EQ(153u, B);
296 EXPECT_EQ(204u, A);
Jane Liu20eafda2017-06-07 10:33:24 -0400297
Lei Zhanga21d5932018-02-05 18:28:38 +0000298 // Change the color of the annotation.
299 ASSERT_TRUE(FPDFAnnot_SetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, 204,
300 153, 102, 51));
301 // Check that the color has been set correctly.
Lei Zhang75c81712018-02-08 17:22:39 +0000302 ASSERT_TRUE(FPDFAnnot_GetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, &R,
Lei Zhanga21d5932018-02-05 18:28:38 +0000303 &G, &B, &A));
304 EXPECT_EQ(204u, R);
305 EXPECT_EQ(153u, G);
306 EXPECT_EQ(102u, B);
307 EXPECT_EQ(51u, A);
Jane Liu20eafda2017-06-07 10:33:24 -0400308
Lei Zhanga21d5932018-02-05 18:28:38 +0000309 // Set the annotation rectangle.
310 FS_RECTF rect;
311 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
312 EXPECT_EQ(0.f, rect.left);
313 EXPECT_EQ(0.f, rect.right);
314 rect.left = 35;
315 rect.bottom = 150;
316 rect.right = 53;
317 rect.top = 165;
318 ASSERT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
319 // Check that the annotation rectangle has been set correctly.
320 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
321 EXPECT_EQ(35.f, rect.left);
322 EXPECT_EQ(150.f, rect.bottom);
323 EXPECT_EQ(53.f, rect.right);
324 EXPECT_EQ(165.f, rect.top);
Jane Liu20eafda2017-06-07 10:33:24 -0400325
Lei Zhanga21d5932018-02-05 18:28:38 +0000326 // Set the content of the annotation.
Lei Zhang4f556b82019-04-08 16:32:41 +0000327 static const wchar_t kContents[] = L"Hello! This is a customized content.";
Lei Zhangf0f67682019-04-08 17:03:21 +0000328 ScopedFPDFWideString text = GetFPDFWideString(kContents);
Lei Zhanga5c1daf2019-01-31 21:56:47 +0000329 ASSERT_TRUE(FPDFAnnot_SetStringValue(
330 annot.get(), pdfium::annotation::kContents, text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +0000331 // Check that the content has been set correctly.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000332 unsigned long length_bytes = FPDFAnnot_GetStringValue(
Lei Zhanga5c1daf2019-01-31 21:56:47 +0000333 annot.get(), pdfium::annotation::kContents, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000334 ASSERT_EQ(74u, length_bytes);
335 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
336 EXPECT_EQ(74u, FPDFAnnot_GetStringValue(annot.get(),
337 pdfium::annotation::kContents,
338 buf.data(), length_bytes));
339 EXPECT_EQ(kContents, GetPlatformWString(buf.data()));
Lei Zhanga21d5932018-02-05 18:28:38 +0000340 }
Jane Liu20eafda2017-06-07 10:33:24 -0400341 UnloadPage(page);
342}
343
Lei Zhang03e5e682019-09-16 19:45:55 +0000344// TODO(crbug.com/pdfium/11): Fix this test and enable.
345#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
346#define MAYBE_AddAndSaveUnderlineAnnotation \
347 DISABLED_AddAndSaveUnderlineAnnotation
348#else
349#define MAYBE_AddAndSaveUnderlineAnnotation AddAndSaveUnderlineAnnotation
350#endif
351TEST_F(FPDFAnnotEmbedderTest, MAYBE_AddAndSaveUnderlineAnnotation) {
Jane Liu20eafda2017-06-07 10:33:24 -0400352 // Open a file with one annotation and load its first page.
353 ASSERT_TRUE(OpenDocument("annotation_highlight_long_content.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000354 FPDF_PAGE page = LoadPage(0);
Jane Liu20eafda2017-06-07 10:33:24 -0400355 ASSERT_TRUE(page);
356
357 // Check that there is a total of one annotation on its first page, and verify
358 // its quadpoints.
359 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
Jane Liu0c6b07d2017-08-15 10:50:22 -0400360 FS_QUADPOINTSF quadpoints;
Lei Zhanga21d5932018-02-05 18:28:38 +0000361 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000362 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000363 ASSERT_TRUE(annot);
Ralf Sippl16381792018-04-12 21:20:26 +0000364 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot.get(), 0, &quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000365 EXPECT_EQ(115.802643f, quadpoints.x1);
366 EXPECT_EQ(718.913940f, quadpoints.y1);
367 EXPECT_EQ(157.211182f, quadpoints.x4);
368 EXPECT_EQ(706.264465f, quadpoints.y4);
369 }
Jane Liu20eafda2017-06-07 10:33:24 -0400370
371 // Add an underline annotation to the page and set its quadpoints.
Lei Zhanga21d5932018-02-05 18:28:38 +0000372 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000373 ScopedFPDFAnnotation annot(
Lei Zhanga21d5932018-02-05 18:28:38 +0000374 FPDFPage_CreateAnnot(page, FPDF_ANNOT_UNDERLINE));
375 ASSERT_TRUE(annot);
376 quadpoints.x1 = 140.802643f;
377 quadpoints.x3 = 140.802643f;
Ralf Sippl16381792018-04-12 21:20:26 +0000378 ASSERT_TRUE(FPDFAnnot_AppendAttachmentPoints(annot.get(), &quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000379 }
Jane Liu20eafda2017-06-07 10:33:24 -0400380
381 // Save the document, closing the page and document.
382 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang75c81712018-02-08 17:22:39 +0000383 UnloadPage(page);
Jane Liu20eafda2017-06-07 10:33:24 -0400384
385 // Open the saved document.
Lei Zhang4f556b82019-04-08 16:32:41 +0000386 static const char kMd5[] = "dba153419f67b7c0c0e3d22d3e8910d5";
Dan Sinclair04e4dc82017-10-18 12:17:14 -0400387
Lei Zhang0b494052019-01-31 21:41:15 +0000388 ASSERT_TRUE(OpenSavedDocument());
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000389 page = LoadSavedPage(0);
Lei Zhang4f556b82019-04-08 16:32:41 +0000390 VerifySavedRendering(page, 612, 792, kMd5);
Jane Liu20eafda2017-06-07 10:33:24 -0400391
392 // Check that the saved document has 2 annotations on the first page
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000393 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
Jane Liu20eafda2017-06-07 10:33:24 -0400394
Lei Zhanga21d5932018-02-05 18:28:38 +0000395 {
396 // Check that the second annotation is an underline annotation and verify
397 // its quadpoints.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000398 ScopedFPDFAnnotation new_annot(FPDFPage_GetAnnot(page, 1));
Lei Zhanga21d5932018-02-05 18:28:38 +0000399 ASSERT_TRUE(new_annot);
400 EXPECT_EQ(FPDF_ANNOT_UNDERLINE, FPDFAnnot_GetSubtype(new_annot.get()));
401 FS_QUADPOINTSF new_quadpoints;
402 ASSERT_TRUE(
Ralf Sippl16381792018-04-12 21:20:26 +0000403 FPDFAnnot_GetAttachmentPoints(new_annot.get(), 0, &new_quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000404 EXPECT_NEAR(quadpoints.x1, new_quadpoints.x1, 0.001f);
405 EXPECT_NEAR(quadpoints.y1, new_quadpoints.y1, 0.001f);
406 EXPECT_NEAR(quadpoints.x4, new_quadpoints.x4, 0.001f);
407 EXPECT_NEAR(quadpoints.y4, new_quadpoints.y4, 0.001f);
408 }
Dan Sinclair04e4dc82017-10-18 12:17:14 -0400409
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000410 CloseSavedPage(page);
Dan Sinclair04e4dc82017-10-18 12:17:14 -0400411 CloseSavedDocument();
Jane Liu20eafda2017-06-07 10:33:24 -0400412}
Jane Liu06462752017-06-27 16:41:14 -0400413
Lei Zhangab41f252018-12-23 03:10:50 +0000414TEST_F(FPDFAnnotEmbedderTest, GetAndSetQuadPoints) {
Ralf Sippl16381792018-04-12 21:20:26 +0000415 // Open a file with four annotations and load its first page.
416 ASSERT_TRUE(OpenDocument("annotation_highlight_square_with_ap.pdf"));
417 FPDF_PAGE page = LoadPage(0);
418 ASSERT_TRUE(page);
419 EXPECT_EQ(4, FPDFPage_GetAnnotCount(page));
420
421 // Retrieve the highlight annotation.
422 FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 0);
423 ASSERT_TRUE(annot);
424 ASSERT_EQ(FPDF_ANNOT_HIGHLIGHT, FPDFAnnot_GetSubtype(annot));
425
426 FS_QUADPOINTSF quadpoints;
427 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot, 0, &quadpoints));
428
429 {
430 // Verify the current one set of quadpoints.
431 ASSERT_EQ(1u, FPDFAnnot_CountAttachmentPoints(annot));
432
433 EXPECT_NEAR(72.0000f, quadpoints.x1, 0.001f);
434 EXPECT_NEAR(720.792f, quadpoints.y1, 0.001f);
435 EXPECT_NEAR(132.055f, quadpoints.x4, 0.001f);
436 EXPECT_NEAR(704.796f, quadpoints.y4, 0.001f);
437 }
438
439 {
440 // Update the quadpoints.
441 FS_QUADPOINTSF new_quadpoints = quadpoints;
442 new_quadpoints.y1 -= 20.f;
443 new_quadpoints.y2 -= 20.f;
444 new_quadpoints.y3 -= 20.f;
445 new_quadpoints.y4 -= 20.f;
446 ASSERT_TRUE(FPDFAnnot_SetAttachmentPoints(annot, 0, &new_quadpoints));
447
448 // Verify added quadpoint set
449 ASSERT_EQ(1u, FPDFAnnot_CountAttachmentPoints(annot));
450 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot, 0, &quadpoints));
451 EXPECT_NEAR(new_quadpoints.x1, quadpoints.x1, 0.001f);
452 EXPECT_NEAR(new_quadpoints.y1, quadpoints.y1, 0.001f);
453 EXPECT_NEAR(new_quadpoints.x4, quadpoints.x4, 0.001f);
454 EXPECT_NEAR(new_quadpoints.y4, quadpoints.y4, 0.001f);
455 }
456
457 {
458 // Append a new set of quadpoints.
459 FS_QUADPOINTSF new_quadpoints = quadpoints;
460 new_quadpoints.y1 += 20.f;
461 new_quadpoints.y2 += 20.f;
462 new_quadpoints.y3 += 20.f;
463 new_quadpoints.y4 += 20.f;
464 ASSERT_TRUE(FPDFAnnot_AppendAttachmentPoints(annot, &new_quadpoints));
465
466 // Verify added quadpoint set
467 ASSERT_EQ(2u, FPDFAnnot_CountAttachmentPoints(annot));
468 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot, 1, &quadpoints));
469 EXPECT_NEAR(new_quadpoints.x1, quadpoints.x1, 0.001f);
470 EXPECT_NEAR(new_quadpoints.y1, quadpoints.y1, 0.001f);
471 EXPECT_NEAR(new_quadpoints.x4, quadpoints.x4, 0.001f);
472 EXPECT_NEAR(new_quadpoints.y4, quadpoints.y4, 0.001f);
473 }
474
475 {
476 // Setting and getting quadpoints at out-of-bound index should fail
477 EXPECT_FALSE(FPDFAnnot_SetAttachmentPoints(annot, 300000, &quadpoints));
478 EXPECT_FALSE(FPDFAnnot_GetAttachmentPoints(annot, 300000, &quadpoints));
479 }
480
481 FPDFPage_CloseAnnot(annot);
482
483 // Retrieve the square annotation
484 FPDF_ANNOTATION squareAnnot = FPDFPage_GetAnnot(page, 2);
485
486 {
487 // Check that attempting to set its quadpoints would fail
488 ASSERT_TRUE(squareAnnot);
489 EXPECT_EQ(FPDF_ANNOT_SQUARE, FPDFAnnot_GetSubtype(squareAnnot));
490 EXPECT_EQ(0u, FPDFAnnot_CountAttachmentPoints(squareAnnot));
491 EXPECT_FALSE(FPDFAnnot_SetAttachmentPoints(squareAnnot, 0, &quadpoints));
492 }
493
494 FPDFPage_CloseAnnot(squareAnnot);
Ralf Sippl16381792018-04-12 21:20:26 +0000495 UnloadPage(page);
496}
497
Lei Zhang03e5e682019-09-16 19:45:55 +0000498// TODO(crbug.com/pdfium/11): Fix this test and enable.
499#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
500#define MAYBE_ModifyRectQuadpointsWithAP DISABLED_ModifyRectQuadpointsWithAP
501#else
502#define MAYBE_ModifyRectQuadpointsWithAP ModifyRectQuadpointsWithAP
503#endif
504TEST_F(FPDFAnnotEmbedderTest, MAYBE_ModifyRectQuadpointsWithAP) {
Lei Zhange4cdac52019-04-30 16:45:57 +0000505#if defined(OS_MACOSX)
Lei Zhang4f556b82019-04-08 16:32:41 +0000506 static const char kMd5Original[] = "63af8432fab95a67cdebb7cd0e514941";
507 static const char kMd5ModifiedHighlight[] =
508 "aec26075011349dec9bace891856b5f2";
509 static const char kMd5ModifiedSquare[] = "057f57a32be95975775e5ec513fdcb56";
Lei Zhange67bcc72019-04-30 18:55:58 +0000510#elif defined(OS_WIN)
Lei Zhang4f556b82019-04-08 16:32:41 +0000511 static const char kMd5Original[] = "0e27376094f11490f74c65f3dc3a42c5";
512 static const char kMd5ModifiedHighlight[] =
513 "66f3caef3a7d488a4fa1ad37fc06310e";
514 static const char kMd5ModifiedSquare[] = "a456dad0bc6801ee2d6408a4394af563";
Jane Liub370e5a2017-08-16 13:24:58 -0400515#else
Lei Zhang4f556b82019-04-08 16:32:41 +0000516 static const char kMd5Original[] = "0e27376094f11490f74c65f3dc3a42c5";
517 static const char kMd5ModifiedHighlight[] =
518 "66f3caef3a7d488a4fa1ad37fc06310e";
519 static const char kMd5ModifiedSquare[] = "a456dad0bc6801ee2d6408a4394af563";
Jane Liub370e5a2017-08-16 13:24:58 -0400520#endif
521
Jane Liu06462752017-06-27 16:41:14 -0400522 // Open a file with four annotations and load its first page.
523 ASSERT_TRUE(OpenDocument("annotation_highlight_square_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000524 FPDF_PAGE page = LoadPage(0);
Jane Liu06462752017-06-27 16:41:14 -0400525 ASSERT_TRUE(page);
526 EXPECT_EQ(4, FPDFPage_GetAnnotCount(page));
527
Jane Liub370e5a2017-08-16 13:24:58 -0400528 // Check that the original file renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000529 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000530 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000531 CompareBitmap(bitmap.get(), 612, 792, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000532 }
Jane Liub370e5a2017-08-16 13:24:58 -0400533
Jane Liu0c6b07d2017-08-15 10:50:22 -0400534 FS_RECTF rect;
Jane Liu0c6b07d2017-08-15 10:50:22 -0400535 FS_RECTF new_rect;
Lei Zhanga21d5932018-02-05 18:28:38 +0000536
537 // Retrieve the highlight annotation which has its AP stream already defined.
538 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000539 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000540 ASSERT_TRUE(annot);
541 EXPECT_EQ(FPDF_ANNOT_HIGHLIGHT, FPDFAnnot_GetSubtype(annot.get()));
542
543 // Check that color cannot be set when an AP stream is defined already.
544 EXPECT_FALSE(FPDFAnnot_SetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, 51,
545 102, 153, 204));
546
547 // Verify its attachment points.
548 FS_QUADPOINTSF quadpoints;
Ralf Sippl16381792018-04-12 21:20:26 +0000549 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot.get(), 0, &quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000550 EXPECT_NEAR(72.0000f, quadpoints.x1, 0.001f);
551 EXPECT_NEAR(720.792f, quadpoints.y1, 0.001f);
552 EXPECT_NEAR(132.055f, quadpoints.x4, 0.001f);
553 EXPECT_NEAR(704.796f, quadpoints.y4, 0.001f);
554
555 // Check that updating the attachment points would succeed.
556 quadpoints.x1 -= 50.f;
557 quadpoints.x2 -= 50.f;
558 quadpoints.x3 -= 50.f;
559 quadpoints.x4 -= 50.f;
Ralf Sippl16381792018-04-12 21:20:26 +0000560 ASSERT_TRUE(FPDFAnnot_SetAttachmentPoints(annot.get(), 0, &quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000561 FS_QUADPOINTSF new_quadpoints;
Ralf Sippl16381792018-04-12 21:20:26 +0000562 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot.get(), 0, &new_quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000563 EXPECT_EQ(quadpoints.x1, new_quadpoints.x1);
564 EXPECT_EQ(quadpoints.y1, new_quadpoints.y1);
565 EXPECT_EQ(quadpoints.x4, new_quadpoints.x4);
566 EXPECT_EQ(quadpoints.y4, new_quadpoints.y4);
567
568 // Check that updating quadpoints does not change the annotation's position.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000569 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000570 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000571 CompareBitmap(bitmap.get(), 612, 792, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000572 }
Lei Zhanga21d5932018-02-05 18:28:38 +0000573
574 // Verify its annotation rectangle.
575 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
576 EXPECT_NEAR(67.7299f, rect.left, 0.001f);
577 EXPECT_NEAR(704.296f, rect.bottom, 0.001f);
578 EXPECT_NEAR(136.325f, rect.right, 0.001f);
579 EXPECT_NEAR(721.292f, rect.top, 0.001f);
580
581 // Check that updating the rectangle would succeed.
582 rect.left -= 60.f;
583 rect.right -= 60.f;
584 ASSERT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
585 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &new_rect));
586 EXPECT_EQ(rect.right, new_rect.right);
587 }
Jane Liu06462752017-06-27 16:41:14 -0400588
Jane Liub370e5a2017-08-16 13:24:58 -0400589 // Check that updating the rectangle changes the annotation's position.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000590 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000591 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000592 CompareBitmap(bitmap.get(), 612, 792, kMd5ModifiedHighlight);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000593 }
Jane Liub370e5a2017-08-16 13:24:58 -0400594
Lei Zhanga21d5932018-02-05 18:28:38 +0000595 {
596 // Retrieve the square annotation which has its AP stream already defined.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000597 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +0000598 ASSERT_TRUE(annot);
599 EXPECT_EQ(FPDF_ANNOT_SQUARE, FPDFAnnot_GetSubtype(annot.get()));
Jane Liu06462752017-06-27 16:41:14 -0400600
Lei Zhanga21d5932018-02-05 18:28:38 +0000601 // Check that updating the rectangle would succeed.
602 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
603 rect.left += 70.f;
604 rect.right += 70.f;
605 ASSERT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
606 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &new_rect));
607 EXPECT_EQ(rect.right, new_rect.right);
Jane Liu06462752017-06-27 16:41:14 -0400608
Lei Zhanga21d5932018-02-05 18:28:38 +0000609 // Check that updating the rectangle changes the square annotation's
610 // position.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000611 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000612 CompareBitmap(bitmap.get(), 612, 792, kMd5ModifiedSquare);
Lei Zhanga21d5932018-02-05 18:28:38 +0000613 }
Jane Liub370e5a2017-08-16 13:24:58 -0400614
Jane Liu06462752017-06-27 16:41:14 -0400615 UnloadPage(page);
616}
Jane Liu8ce58f52017-06-29 13:40:22 -0400617
Lei Zhangab41f252018-12-23 03:10:50 +0000618TEST_F(FPDFAnnotEmbedderTest, CountAttachmentPoints) {
Henrique Nakashima5098b252018-03-26 21:46:00 +0000619 // Open a file with multiline markup annotations.
620 ASSERT_TRUE(OpenDocument("annotation_markup_multiline_no_ap.pdf"));
621 FPDF_PAGE page = LoadPage(0);
622 ASSERT_TRUE(page);
623 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000624 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Henrique Nakashima5098b252018-03-26 21:46:00 +0000625 ASSERT_TRUE(annot);
626
627 // This is a three line annotation.
628 EXPECT_EQ(3u, FPDFAnnot_CountAttachmentPoints(annot.get()));
629 }
630 UnloadPage(page);
631
632 // null annotation should return 0
633 EXPECT_EQ(0u, FPDFAnnot_CountAttachmentPoints(nullptr));
634}
635
Lei Zhangab41f252018-12-23 03:10:50 +0000636TEST_F(FPDFAnnotEmbedderTest, RemoveAnnotation) {
Jane Liu8ce58f52017-06-29 13:40:22 -0400637 // Open a file with 3 annotations on its first page.
638 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
Tom Sepez507d0192018-11-07 16:37:51 +0000639 FPDF_PAGE page = LoadPageNoEvents(0);
Jane Liu8ce58f52017-06-29 13:40:22 -0400640 ASSERT_TRUE(page);
641 EXPECT_EQ(3, FPDFPage_GetAnnotCount(page));
642
Jane Liu0c6b07d2017-08-15 10:50:22 -0400643 FS_RECTF rect;
Jane Liu8ce58f52017-06-29 13:40:22 -0400644
Lei Zhanga21d5932018-02-05 18:28:38 +0000645 // Check that the annotations have the expected rectangle coordinates.
646 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000647 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000648 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
649 EXPECT_NEAR(86.1971f, rect.left, 0.001f);
650 }
Jane Liu8ce58f52017-06-29 13:40:22 -0400651
Lei Zhanga21d5932018-02-05 18:28:38 +0000652 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000653 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 1));
Lei Zhanga21d5932018-02-05 18:28:38 +0000654 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
655 EXPECT_NEAR(149.8127f, rect.left, 0.001f);
656 }
657
658 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000659 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +0000660 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
661 EXPECT_NEAR(351.8204f, rect.left, 0.001f);
662 }
Jane Liu8ce58f52017-06-29 13:40:22 -0400663
664 // Check that nothing happens when attempting to remove an annotation with an
665 // out-of-bound index.
666 EXPECT_FALSE(FPDFPage_RemoveAnnot(page, 4));
667 EXPECT_FALSE(FPDFPage_RemoveAnnot(page, -1));
668 EXPECT_EQ(3, FPDFPage_GetAnnotCount(page));
669
670 // Remove the second annotation.
671 EXPECT_TRUE(FPDFPage_RemoveAnnot(page, 1));
672 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
673 EXPECT_FALSE(FPDFPage_GetAnnot(page, 2));
674
675 // Save the document, closing the page and document.
676 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Tom Sepez507d0192018-11-07 16:37:51 +0000677 UnloadPageNoEvents(page);
Jane Liu8ce58f52017-06-29 13:40:22 -0400678
Dan Sinclair04e4dc82017-10-18 12:17:14 -0400679 // TODO(npm): VerifySavedRendering changes annot rect dimensions by 1??
Jane Liu8ce58f52017-06-29 13:40:22 -0400680 // Open the saved document.
681 std::string new_file = GetString();
682 FPDF_FILEACCESS file_access;
683 memset(&file_access, 0, sizeof(file_access));
684 file_access.m_FileLen = new_file.size();
685 file_access.m_GetBlock = GetBlockFromString;
686 file_access.m_Param = &new_file;
687 FPDF_DOCUMENT new_doc = FPDF_LoadCustomDocument(&file_access, nullptr);
688 ASSERT_TRUE(new_doc);
689 FPDF_PAGE new_page = FPDF_LoadPage(new_doc, 0);
690 ASSERT_TRUE(new_page);
691
692 // Check that the saved document has 2 annotations on the first page.
693 EXPECT_EQ(2, FPDFPage_GetAnnotCount(new_page));
694
Lei Zhanga21d5932018-02-05 18:28:38 +0000695 // Check that the remaining 2 annotations are the original 1st and 3rd ones
696 // by verifying their rectangle coordinates.
697 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000698 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(new_page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000699 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
700 EXPECT_NEAR(86.1971f, rect.left, 0.001f);
701 }
Jane Liu8ce58f52017-06-29 13:40:22 -0400702
Lei Zhanga21d5932018-02-05 18:28:38 +0000703 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000704 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(new_page, 1));
Lei Zhanga21d5932018-02-05 18:28:38 +0000705 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
706 EXPECT_NEAR(351.8204f, rect.left, 0.001f);
707 }
Jane Liubaa7ff42017-06-29 19:18:23 -0400708 FPDF_ClosePage(new_page);
709 FPDF_CloseDocument(new_doc);
710}
Jane Liu8ce58f52017-06-29 13:40:22 -0400711
Lei Zhang03e5e682019-09-16 19:45:55 +0000712// TODO(crbug.com/pdfium/11): Fix this test and enable.
713#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
714#define MAYBE_AddAndModifyPath DISABLED_AddAndModifyPath
715#else
716#define MAYBE_AddAndModifyPath AddAndModifyPath
717#endif
718TEST_F(FPDFAnnotEmbedderTest, MAYBE_AddAndModifyPath) {
Lei Zhange4cdac52019-04-30 16:45:57 +0000719#if defined(OS_MACOSX)
Lei Zhang4f556b82019-04-08 16:32:41 +0000720 static const char kMd5Original[] = "c35408717759562d1f8bf33d317483d2";
721 static const char kMd5ModifiedPath[] = "9059723a045e17478753d2f0eb33bc03";
722 static const char kMd5TwoPaths[] = "7eed0cfba780f1d4dd8068f717d3a6bf";
723 static const char kMd5NewAnnot[] = "1de8212d43b7066a6df042095c2aca61";
Lei Zhange67bcc72019-04-30 18:55:58 +0000724#elif defined(OS_WIN)
Lei Zhanga2b70732019-06-25 08:34:22 +0000725 static const char kMd5Original[] = "6aa001a77ec05d0f1b0d1d22e28744d4";
726 static const char kMd5ModifiedPath[] = "a7a8d675a6ddbcbdfecee65a33ba19e1";
727 static const char kMd5TwoPaths[] = "7c0bdd4552329704c47a7cce47edbbd6";
728 static const char kMd5NewAnnot[] = "3c48d492b4f62941fed0fb62f729f31e";
Jane Liubaa7ff42017-06-29 19:18:23 -0400729#else
Lei Zhanga2b70732019-06-25 08:34:22 +0000730 static const char kMd5Original[] = "b42cef463483e668eaf4055a65e4f1f5";
731 static const char kMd5ModifiedPath[] = "6ff77d6d1fec4ea571fabe0c7a19b517";
732 static const char kMd5TwoPaths[] = "ca37ad549e74ac5b359a055708f3e7b6";
733 static const char kMd5NewAnnot[] = "0d7a0e33fbf41ff7fa5d732ab2c5edff";
Jane Liubaa7ff42017-06-29 19:18:23 -0400734#endif
735
736 // Open a file with two annotations and load its first page.
737 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000738 FPDF_PAGE page = LoadPage(0);
Jane Liubaa7ff42017-06-29 19:18:23 -0400739 ASSERT_TRUE(page);
740 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
741
742 // Check that the page renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000743 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000744 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000745 CompareBitmap(bitmap.get(), 595, 842, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000746 }
Jane Liubaa7ff42017-06-29 19:18:23 -0400747
Lei Zhanga21d5932018-02-05 18:28:38 +0000748 {
749 // Retrieve the stamp annotation which has its AP stream already defined.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000750 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000751 ASSERT_TRUE(annot);
Jane Liubaa7ff42017-06-29 19:18:23 -0400752
Lei Zhanga21d5932018-02-05 18:28:38 +0000753 // Check that this annotation has one path object and retrieve it.
754 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000755 ASSERT_EQ(32, FPDFPage_CountObjects(page));
Lei Zhanga21d5932018-02-05 18:28:38 +0000756 FPDF_PAGEOBJECT path = FPDFAnnot_GetObject(annot.get(), 1);
757 EXPECT_FALSE(path);
758 path = FPDFAnnot_GetObject(annot.get(), 0);
759 EXPECT_EQ(FPDF_PAGEOBJ_PATH, FPDFPageObj_GetType(path));
760 EXPECT_TRUE(path);
Jane Liubaa7ff42017-06-29 19:18:23 -0400761
Lei Zhanga21d5932018-02-05 18:28:38 +0000762 // Modify the color of the path object.
Lei Zhang3475b482019-05-13 18:30:57 +0000763 EXPECT_TRUE(FPDFPageObj_SetStrokeColor(path, 0, 0, 0, 255));
Lei Zhanga21d5932018-02-05 18:28:38 +0000764 EXPECT_TRUE(FPDFAnnot_UpdateObject(annot.get(), path));
Jane Liubaa7ff42017-06-29 19:18:23 -0400765
Lei Zhanga21d5932018-02-05 18:28:38 +0000766 // Check that the page with the modified annotation renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000767 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000768 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000769 CompareBitmap(bitmap.get(), 595, 842, kMd5ModifiedPath);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000770 }
Jane Liu7a9a38b2017-07-11 13:47:37 -0400771
Lei Zhanga21d5932018-02-05 18:28:38 +0000772 // Add a second path object to the same annotation.
773 FPDF_PAGEOBJECT dot = FPDFPageObj_CreateNewPath(7, 84);
774 EXPECT_TRUE(FPDFPath_BezierTo(dot, 9, 86, 10, 87, 11, 88));
Lei Zhang3475b482019-05-13 18:30:57 +0000775 EXPECT_TRUE(FPDFPageObj_SetStrokeColor(dot, 255, 0, 0, 100));
776 EXPECT_TRUE(FPDFPageObj_SetStrokeWidth(dot, 14));
Lei Zhanga21d5932018-02-05 18:28:38 +0000777 EXPECT_TRUE(FPDFPath_SetDrawMode(dot, 0, 1));
778 EXPECT_TRUE(FPDFAnnot_AppendObject(annot.get(), dot));
779 EXPECT_EQ(2, FPDFAnnot_GetObjectCount(annot.get()));
Jane Liu7a9a38b2017-07-11 13:47:37 -0400780
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000781 // The object is in the annontation, not in the page, so the page object
782 // array should not change.
783 ASSERT_EQ(32, FPDFPage_CountObjects(page));
784
Lei Zhanga21d5932018-02-05 18:28:38 +0000785 // Check that the page with an annotation with two paths renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000786 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000787 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000788 CompareBitmap(bitmap.get(), 595, 842, kMd5TwoPaths);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000789 }
Jane Liu7a9a38b2017-07-11 13:47:37 -0400790
Lei Zhanga21d5932018-02-05 18:28:38 +0000791 // Delete the newly added path object.
792 EXPECT_TRUE(FPDFAnnot_RemoveObject(annot.get(), 1));
793 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000794 ASSERT_EQ(32, FPDFPage_CountObjects(page));
Lei Zhanga21d5932018-02-05 18:28:38 +0000795 }
Jane Liu7a9a38b2017-07-11 13:47:37 -0400796
797 // Check that the page renders the same as before.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000798 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000799 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000800 CompareBitmap(bitmap.get(), 595, 842, kMd5ModifiedPath);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000801 }
Jane Liubaa7ff42017-06-29 19:18:23 -0400802
Jane Liubaa7ff42017-06-29 19:18:23 -0400803 FS_RECTF rect;
Jane Liubaa7ff42017-06-29 19:18:23 -0400804
Lei Zhanga21d5932018-02-05 18:28:38 +0000805 {
806 // Create another stamp annotation and set its annotation rectangle.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000807 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP));
Lei Zhanga21d5932018-02-05 18:28:38 +0000808 ASSERT_TRUE(annot);
809 rect.left = 200.f;
810 rect.bottom = 400.f;
811 rect.right = 500.f;
812 rect.top = 600.f;
813 EXPECT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
Jane Liubaa7ff42017-06-29 19:18:23 -0400814
Lei Zhanga21d5932018-02-05 18:28:38 +0000815 // Add a new path to the annotation.
816 FPDF_PAGEOBJECT check = FPDFPageObj_CreateNewPath(200, 500);
817 EXPECT_TRUE(FPDFPath_LineTo(check, 300, 400));
818 EXPECT_TRUE(FPDFPath_LineTo(check, 500, 600));
819 EXPECT_TRUE(FPDFPath_MoveTo(check, 350, 550));
820 EXPECT_TRUE(FPDFPath_LineTo(check, 450, 450));
Lei Zhang3475b482019-05-13 18:30:57 +0000821 EXPECT_TRUE(FPDFPageObj_SetStrokeColor(check, 0, 255, 255, 180));
822 EXPECT_TRUE(FPDFPageObj_SetStrokeWidth(check, 8.35f));
Lei Zhanga21d5932018-02-05 18:28:38 +0000823 EXPECT_TRUE(FPDFPath_SetDrawMode(check, 0, 1));
824 EXPECT_TRUE(FPDFAnnot_AppendObject(annot.get(), check));
825 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
826
827 // Check that the annotation's bounding box came from its rectangle.
828 FS_RECTF new_rect;
829 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &new_rect));
830 EXPECT_EQ(rect.left, new_rect.left);
831 EXPECT_EQ(rect.bottom, new_rect.bottom);
832 EXPECT_EQ(rect.right, new_rect.right);
833 EXPECT_EQ(rect.top, new_rect.top);
834 }
Jane Liubaa7ff42017-06-29 19:18:23 -0400835
836 // Save the document, closing the page and document.
Jane Liubaa7ff42017-06-29 19:18:23 -0400837 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang75c81712018-02-08 17:22:39 +0000838 UnloadPage(page);
Jane Liubaa7ff42017-06-29 19:18:23 -0400839
840 // Open the saved document.
Lei Zhang0b494052019-01-31 21:41:15 +0000841 ASSERT_TRUE(OpenSavedDocument());
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000842 page = LoadSavedPage(0);
Lei Zhang4f556b82019-04-08 16:32:41 +0000843 VerifySavedRendering(page, 595, 842, kMd5NewAnnot);
Jane Liubaa7ff42017-06-29 19:18:23 -0400844
Jane Liu36567742017-07-06 11:13:35 -0400845 // Check that the document has a correct count of annotations and objects.
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000846 EXPECT_EQ(3, FPDFPage_GetAnnotCount(page));
Jane Liubaa7ff42017-06-29 19:18:23 -0400847
Lei Zhanga21d5932018-02-05 18:28:38 +0000848 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000849 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +0000850 ASSERT_TRUE(annot);
851 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
Jane Liubaa7ff42017-06-29 19:18:23 -0400852
Lei Zhanga21d5932018-02-05 18:28:38 +0000853 // Check that the new annotation's rectangle is as defined.
854 FS_RECTF new_rect;
855 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &new_rect));
856 EXPECT_EQ(rect.left, new_rect.left);
857 EXPECT_EQ(rect.bottom, new_rect.bottom);
858 EXPECT_EQ(rect.right, new_rect.right);
859 EXPECT_EQ(rect.top, new_rect.top);
860 }
861
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000862 CloseSavedPage(page);
Dan Sinclair04e4dc82017-10-18 12:17:14 -0400863 CloseSavedDocument();
Jane Liu8ce58f52017-06-29 13:40:22 -0400864}
Jane Liub137e752017-07-05 15:04:33 -0400865
Lei Zhangab41f252018-12-23 03:10:50 +0000866TEST_F(FPDFAnnotEmbedderTest, ModifyAnnotationFlags) {
Jane Liub137e752017-07-05 15:04:33 -0400867 // Open a file with an annotation and load its first page.
868 ASSERT_TRUE(OpenDocument("annotation_highlight_rollover_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000869 FPDF_PAGE page = LoadPage(0);
Jane Liub137e752017-07-05 15:04:33 -0400870 ASSERT_TRUE(page);
871
872 // Check that the page renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000873 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000874 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000875 CompareBitmap(bitmap.get(), 612, 792, "dc98f06da047bd8aabfa99562d2cbd1e");
876 }
Jane Liub137e752017-07-05 15:04:33 -0400877
Lei Zhanga21d5932018-02-05 18:28:38 +0000878 {
879 // Retrieve the annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000880 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000881 ASSERT_TRUE(annot);
Jane Liub137e752017-07-05 15:04:33 -0400882
Lei Zhanga21d5932018-02-05 18:28:38 +0000883 // Check that the original flag values are as expected.
884 int flags = FPDFAnnot_GetFlags(annot.get());
885 EXPECT_FALSE(flags & FPDF_ANNOT_FLAG_HIDDEN);
886 EXPECT_TRUE(flags & FPDF_ANNOT_FLAG_PRINT);
Jane Liub137e752017-07-05 15:04:33 -0400887
Lei Zhanga21d5932018-02-05 18:28:38 +0000888 // Set the HIDDEN flag.
889 flags |= FPDF_ANNOT_FLAG_HIDDEN;
890 EXPECT_TRUE(FPDFAnnot_SetFlags(annot.get(), flags));
891 flags = FPDFAnnot_GetFlags(annot.get());
892 EXPECT_TRUE(flags & FPDF_ANNOT_FLAG_HIDDEN);
893 EXPECT_TRUE(flags & FPDF_ANNOT_FLAG_PRINT);
Jane Liub137e752017-07-05 15:04:33 -0400894
Lei Zhanga21d5932018-02-05 18:28:38 +0000895 // Check that the page renders correctly without rendering the annotation.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000896 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000897 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000898 CompareBitmap(bitmap.get(), 612, 792, "1940568c9ba33bac5d0b1ee9558c76b3");
899 }
Jane Liub137e752017-07-05 15:04:33 -0400900
Lei Zhanga21d5932018-02-05 18:28:38 +0000901 // Unset the HIDDEN flag.
902 EXPECT_TRUE(FPDFAnnot_SetFlags(annot.get(), FPDF_ANNOT_FLAG_NONE));
903 EXPECT_FALSE(FPDFAnnot_GetFlags(annot.get()));
904 flags &= ~FPDF_ANNOT_FLAG_HIDDEN;
905 EXPECT_TRUE(FPDFAnnot_SetFlags(annot.get(), flags));
906 flags = FPDFAnnot_GetFlags(annot.get());
907 EXPECT_FALSE(flags & FPDF_ANNOT_FLAG_HIDDEN);
908 EXPECT_TRUE(flags & FPDF_ANNOT_FLAG_PRINT);
Jane Liub137e752017-07-05 15:04:33 -0400909
Lei Zhanga21d5932018-02-05 18:28:38 +0000910 // Check that the page renders correctly as before.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000911 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000912 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000913 CompareBitmap(bitmap.get(), 612, 792, "dc98f06da047bd8aabfa99562d2cbd1e");
914 }
Lei Zhanga21d5932018-02-05 18:28:38 +0000915 }
Jane Liub137e752017-07-05 15:04:33 -0400916
Jane Liub137e752017-07-05 15:04:33 -0400917 UnloadPage(page);
918}
Jane Liu36567742017-07-06 11:13:35 -0400919
Lei Zhang03e5e682019-09-16 19:45:55 +0000920// TODO(crbug.com/pdfium/11): Fix this test and enable.
921#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
922#define MAYBE_AddAndModifyImage DISABLED_AddAndModifyImage
923#else
924#define MAYBE_AddAndModifyImage AddAndModifyImage
925#endif
926TEST_F(FPDFAnnotEmbedderTest, MAYBE_AddAndModifyImage) {
Lei Zhange4cdac52019-04-30 16:45:57 +0000927#if defined(OS_MACOSX)
Lei Zhang4f556b82019-04-08 16:32:41 +0000928 static const char kMd5Original[] = "c35408717759562d1f8bf33d317483d2";
929 static const char kMd5NewImage[] = "ff012f5697436dfcaec25b32d1333596";
930 static const char kMd5ModifiedImage[] = "86cf8cb2755a7a2046a543e66d9c1e61";
Lei Zhange67bcc72019-04-30 18:55:58 +0000931#elif defined(OS_WIN)
Lei Zhanga2b70732019-06-25 08:34:22 +0000932 static const char kMd5Original[] = "6aa001a77ec05d0f1b0d1d22e28744d4";
933 static const char kMd5NewImage[] = "3d77d06a971bcb9fb54db082f1082c8b";
934 static const char kMd5ModifiedImage[] = "dc4f4afc26c345418330d31c065020e1";
Jane Liu36567742017-07-06 11:13:35 -0400935#else
Lei Zhanga2b70732019-06-25 08:34:22 +0000936 static const char kMd5Original[] = "b42cef463483e668eaf4055a65e4f1f5";
937 static const char kMd5NewImage[] = "528e6243dc29d54f36b61e0d3287d935";
938 static const char kMd5ModifiedImage[] = "6d9e59f3e57a1ff82fb258356b7eb731";
Jane Liu36567742017-07-06 11:13:35 -0400939#endif
940
941 // Open a file with two annotations and load its first page.
942 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000943 FPDF_PAGE page = LoadPage(0);
Jane Liu36567742017-07-06 11:13:35 -0400944 ASSERT_TRUE(page);
945 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
946
947 // Check that the page renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000948 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000949 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000950 CompareBitmap(bitmap.get(), 595, 842, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000951 }
Jane Liu36567742017-07-06 11:13:35 -0400952
Jane Liu36567742017-07-06 11:13:35 -0400953 constexpr int kBitmapSize = 200;
Lei Zhanga21d5932018-02-05 18:28:38 +0000954 FPDF_BITMAP image_bitmap;
955
956 {
957 // Create a stamp annotation and set its annotation rectangle.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000958 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP));
Lei Zhanga21d5932018-02-05 18:28:38 +0000959 ASSERT_TRUE(annot);
960 FS_RECTF rect;
961 rect.left = 200.f;
962 rect.bottom = 600.f;
963 rect.right = 400.f;
964 rect.top = 800.f;
965 EXPECT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
966
967 // Add a solid-color translucent image object to the new annotation.
968 image_bitmap = FPDFBitmap_Create(kBitmapSize, kBitmapSize, 1);
969 FPDFBitmap_FillRect(image_bitmap, 0, 0, kBitmapSize, kBitmapSize,
970 0xeeeecccc);
971 EXPECT_EQ(kBitmapSize, FPDFBitmap_GetWidth(image_bitmap));
972 EXPECT_EQ(kBitmapSize, FPDFBitmap_GetHeight(image_bitmap));
973 FPDF_PAGEOBJECT image_object = FPDFPageObj_NewImageObj(document());
974 ASSERT_TRUE(FPDFImageObj_SetBitmap(&page, 0, image_object, image_bitmap));
975 ASSERT_TRUE(FPDFImageObj_SetMatrix(image_object, kBitmapSize, 0, 0,
976 kBitmapSize, 0, 0));
977 FPDFPageObj_Transform(image_object, 1, 0, 0, 1, 200, 600);
978 EXPECT_TRUE(FPDFAnnot_AppendObject(annot.get(), image_object));
979 }
Jane Liu36567742017-07-06 11:13:35 -0400980
981 // Check that the page renders correctly with the new image object.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000982 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000983 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000984 CompareBitmap(bitmap.get(), 595, 842, kMd5NewImage);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000985 }
Jane Liu36567742017-07-06 11:13:35 -0400986
Lei Zhanga21d5932018-02-05 18:28:38 +0000987 {
988 // Retrieve the newly added stamp annotation and its image object.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000989 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +0000990 ASSERT_TRUE(annot);
991 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
992 FPDF_PAGEOBJECT image_object = FPDFAnnot_GetObject(annot.get(), 0);
993 EXPECT_EQ(FPDF_PAGEOBJ_IMAGE, FPDFPageObj_GetType(image_object));
Jane Liu36567742017-07-06 11:13:35 -0400994
Lei Zhanga21d5932018-02-05 18:28:38 +0000995 // Modify the image in the new annotation.
996 FPDFBitmap_FillRect(image_bitmap, 0, 0, kBitmapSize, kBitmapSize,
997 0xff000000);
998 ASSERT_TRUE(FPDFImageObj_SetBitmap(&page, 0, image_object, image_bitmap));
999 EXPECT_TRUE(FPDFAnnot_UpdateObject(annot.get(), image_object));
1000 }
Jane Liu36567742017-07-06 11:13:35 -04001001
1002 // Save the document, closing the page and document.
1003 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang75c81712018-02-08 17:22:39 +00001004 UnloadPage(page);
Dan Sinclair04e4dc82017-10-18 12:17:14 -04001005 FPDFBitmap_Destroy(image_bitmap);
Jane Liu36567742017-07-06 11:13:35 -04001006
1007 // Test that the saved document renders the modified image object correctly.
Lei Zhang4f556b82019-04-08 16:32:41 +00001008 VerifySavedDocument(595, 842, kMd5ModifiedImage);
Jane Liu36567742017-07-06 11:13:35 -04001009}
1010
Lei Zhang03e5e682019-09-16 19:45:55 +00001011// TODO(crbug.com/pdfium/11): Fix this test and enable.
1012#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
1013#define MAYBE_AddAndModifyText DISABLED_AddAndModifyText
1014#else
1015#define MAYBE_AddAndModifyText AddAndModifyText
1016#endif
1017TEST_F(FPDFAnnotEmbedderTest, MAYBE_AddAndModifyText) {
Lei Zhange4cdac52019-04-30 16:45:57 +00001018#if defined(OS_MACOSX)
Lei Zhang4f556b82019-04-08 16:32:41 +00001019 static const char kMd5Original[] = "c35408717759562d1f8bf33d317483d2";
1020 static const char kMd5NewText[] = "60031c1b0330cf1e1575f7d46687d429";
1021 static const char kMd5ModifiedText[] = "79f5cfb0b07caaf936f65f6a7a57ce77";
Lei Zhange67bcc72019-04-30 18:55:58 +00001022#elif defined(OS_WIN)
Lei Zhanga2b70732019-06-25 08:34:22 +00001023 static const char kMd5Original[] = "6aa001a77ec05d0f1b0d1d22e28744d4";
1024 static const char kMd5NewText[] = "204cc01749a70b8afc246a4ca33c7eb6";
1025 static const char kMd5ModifiedText[] = "641261a45e8dfd68c89b80bfd237660d";
Jane Liu36567742017-07-06 11:13:35 -04001026#else
Lei Zhanga2b70732019-06-25 08:34:22 +00001027 static const char kMd5Original[] = "b42cef463483e668eaf4055a65e4f1f5";
1028 static const char kMd5NewText[] = "00197ad6206f763febad5719e5935306";
1029 static const char kMd5ModifiedText[] = "85853bc0aaa5a4e3af04e58b9cbfff23";
Jane Liu36567742017-07-06 11:13:35 -04001030#endif
1031
1032 // Open a file with two annotations and load its first page.
1033 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001034 FPDF_PAGE page = LoadPage(0);
Jane Liu36567742017-07-06 11:13:35 -04001035 ASSERT_TRUE(page);
1036 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
1037
1038 // Check that the page renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +00001039 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001040 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +00001041 CompareBitmap(bitmap.get(), 595, 842, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +00001042 }
Jane Liu36567742017-07-06 11:13:35 -04001043
Lei Zhanga21d5932018-02-05 18:28:38 +00001044 {
1045 // Create a stamp annotation and set its annotation rectangle.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001046 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP));
Lei Zhanga21d5932018-02-05 18:28:38 +00001047 ASSERT_TRUE(annot);
1048 FS_RECTF rect;
1049 rect.left = 200.f;
1050 rect.bottom = 550.f;
1051 rect.right = 450.f;
1052 rect.top = 650.f;
1053 EXPECT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
Jane Liu36567742017-07-06 11:13:35 -04001054
Lei Zhanga21d5932018-02-05 18:28:38 +00001055 // Add a translucent text object to the new annotation.
1056 FPDF_PAGEOBJECT text_object =
1057 FPDFPageObj_NewTextObj(document(), "Arial", 12.0f);
1058 EXPECT_TRUE(text_object);
Lei Zhangf0f67682019-04-08 17:03:21 +00001059 ScopedFPDFWideString text =
Lei Zhanga21d5932018-02-05 18:28:38 +00001060 GetFPDFWideString(L"I'm a translucent text laying on other text.");
1061 EXPECT_TRUE(FPDFText_SetText(text_object, text.get()));
Lei Zhang3475b482019-05-13 18:30:57 +00001062 EXPECT_TRUE(FPDFPageObj_SetFillColor(text_object, 0, 0, 255, 150));
Lei Zhanga21d5932018-02-05 18:28:38 +00001063 FPDFPageObj_Transform(text_object, 1, 0, 0, 1, 200, 600);
1064 EXPECT_TRUE(FPDFAnnot_AppendObject(annot.get(), text_object));
1065 }
Jane Liu36567742017-07-06 11:13:35 -04001066
1067 // Check that the page renders correctly with the new text object.
Lei Zhangc113c7a2018-02-12 14:58:44 +00001068 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001069 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +00001070 CompareBitmap(bitmap.get(), 595, 842, kMd5NewText);
Lei Zhangc113c7a2018-02-12 14:58:44 +00001071 }
Jane Liu36567742017-07-06 11:13:35 -04001072
Lei Zhanga21d5932018-02-05 18:28:38 +00001073 {
1074 // Retrieve the newly added stamp annotation and its text object.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001075 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +00001076 ASSERT_TRUE(annot);
1077 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
1078 FPDF_PAGEOBJECT text_object = FPDFAnnot_GetObject(annot.get(), 0);
1079 EXPECT_EQ(FPDF_PAGEOBJ_TEXT, FPDFPageObj_GetType(text_object));
Jane Liu36567742017-07-06 11:13:35 -04001080
Lei Zhanga21d5932018-02-05 18:28:38 +00001081 // Modify the text in the new annotation.
Lei Zhangf0f67682019-04-08 17:03:21 +00001082 ScopedFPDFWideString new_text = GetFPDFWideString(L"New text!");
Lei Zhanga21d5932018-02-05 18:28:38 +00001083 EXPECT_TRUE(FPDFText_SetText(text_object, new_text.get()));
1084 EXPECT_TRUE(FPDFAnnot_UpdateObject(annot.get(), text_object));
1085 }
Jane Liu36567742017-07-06 11:13:35 -04001086
1087 // Check that the page renders correctly with the modified text object.
Lei Zhangc113c7a2018-02-12 14:58:44 +00001088 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001089 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +00001090 CompareBitmap(bitmap.get(), 595, 842, kMd5ModifiedText);
Lei Zhangc113c7a2018-02-12 14:58:44 +00001091 }
Jane Liu36567742017-07-06 11:13:35 -04001092
1093 // Remove the new annotation, and check that the page renders as before.
1094 EXPECT_TRUE(FPDFPage_RemoveAnnot(page, 2));
Lei Zhangc113c7a2018-02-12 14:58:44 +00001095 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001096 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +00001097 CompareBitmap(bitmap.get(), 595, 842, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +00001098 }
Jane Liu36567742017-07-06 11:13:35 -04001099
1100 UnloadPage(page);
1101}
Jane Liu2e1a32b2017-07-06 12:01:25 -04001102
Lei Zhang03e5e682019-09-16 19:45:55 +00001103// TODO(crbug.com/pdfium/11): Fix this test and enable.
1104#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
1105#define MAYBE_GetSetStringValue DISABLED_GetSetStringValue
1106#else
1107#define MAYBE_GetSetStringValue GetSetStringValue
1108#endif
1109TEST_F(FPDFAnnotEmbedderTest, MAYBE_GetSetStringValue) {
Jane Liu2e1a32b2017-07-06 12:01:25 -04001110 // Open a file with four annotations and load its first page.
1111 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001112 FPDF_PAGE page = LoadPage(0);
Jane Liu2e1a32b2017-07-06 12:01:25 -04001113 ASSERT_TRUE(page);
1114
Lei Zhang4f556b82019-04-08 16:32:41 +00001115 static const wchar_t kNewDate[] = L"D:201706282359Z00'00'";
Jane Liu2e1a32b2017-07-06 12:01:25 -04001116
Lei Zhanga21d5932018-02-05 18:28:38 +00001117 {
1118 // Retrieve the first annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001119 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001120 ASSERT_TRUE(annot);
1121
1122 // Check that a non-existent key does not exist.
1123 EXPECT_FALSE(FPDFAnnot_HasKey(annot.get(), "none"));
1124
1125 // Check that the string value of a non-string dictionary entry is empty.
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001126 EXPECT_TRUE(FPDFAnnot_HasKey(annot.get(), pdfium::annotation::kAP));
Lei Zhanga21d5932018-02-05 18:28:38 +00001127 EXPECT_EQ(FPDF_OBJECT_REFERENCE,
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001128 FPDFAnnot_GetValueType(annot.get(), pdfium::annotation::kAP));
1129 EXPECT_EQ(2u, FPDFAnnot_GetStringValue(annot.get(), pdfium::annotation::kAP,
1130 nullptr, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001131
1132 // Check that the string value of the hash is correct.
Lei Zhang4f556b82019-04-08 16:32:41 +00001133 static const char kHashKey[] = "AAPL:Hash";
Lei Zhanga21d5932018-02-05 18:28:38 +00001134 EXPECT_EQ(FPDF_OBJECT_NAME, FPDFAnnot_GetValueType(annot.get(), kHashKey));
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001135 unsigned long length_bytes =
Lei Zhanga21d5932018-02-05 18:28:38 +00001136 FPDFAnnot_GetStringValue(annot.get(), kHashKey, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001137 ASSERT_EQ(66u, length_bytes);
1138 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
1139 EXPECT_EQ(66u, FPDFAnnot_GetStringValue(annot.get(), kHashKey, buf.data(),
1140 length_bytes));
1141 EXPECT_EQ(L"395fbcb98d558681742f30683a62a2ad",
1142 GetPlatformWString(buf.data()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001143
1144 // Check that the string value of the modified date is correct.
1145 EXPECT_EQ(FPDF_OBJECT_NAME, FPDFAnnot_GetValueType(annot.get(), kHashKey));
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001146 length_bytes = FPDFAnnot_GetStringValue(annot.get(), pdfium::annotation::kM,
1147 nullptr, 0);
1148 ASSERT_EQ(44u, length_bytes);
1149 buf = GetFPDFWideStringBuffer(length_bytes);
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001150 EXPECT_EQ(44u, FPDFAnnot_GetStringValue(annot.get(), pdfium::annotation::kM,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001151 buf.data(), length_bytes));
1152 EXPECT_EQ(L"D:201706071721Z00'00'", GetPlatformWString(buf.data()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001153
1154 // Update the date entry for the annotation.
Lei Zhangf0f67682019-04-08 17:03:21 +00001155 ScopedFPDFWideString text = GetFPDFWideString(kNewDate);
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001156 EXPECT_TRUE(FPDFAnnot_SetStringValue(annot.get(), pdfium::annotation::kM,
1157 text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001158 }
Jane Liu2e1a32b2017-07-06 12:01:25 -04001159
1160 // Save the document, closing the page and document.
Jane Liu2e1a32b2017-07-06 12:01:25 -04001161 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang75c81712018-02-08 17:22:39 +00001162 UnloadPage(page);
Jane Liu2e1a32b2017-07-06 12:01:25 -04001163
Lei Zhange4cdac52019-04-30 16:45:57 +00001164#if defined(OS_MACOSX)
Lei Zhang4f556b82019-04-08 16:32:41 +00001165 static const char kMd5[] = "4d64e61c9c0f8c60ab3cc3234bb73b1c";
Lei Zhange67bcc72019-04-30 18:55:58 +00001166#elif defined(OS_WIN)
Lei Zhanga2b70732019-06-25 08:34:22 +00001167 static const char kMd5[] = "20b612ebd46babcb44c48c903e2c5a48";
Jane Liu2e1a32b2017-07-06 12:01:25 -04001168#else
Lei Zhanga2b70732019-06-25 08:34:22 +00001169 static const char kMd5[] = "1d7bea2042c6fea0558ff2aef05811b5";
Jane Liu2e1a32b2017-07-06 12:01:25 -04001170#endif
Dan Sinclair971a6742018-03-28 19:23:25 +00001171
1172 // Open the saved annotation.
Lei Zhang0b494052019-01-31 21:41:15 +00001173 ASSERT_TRUE(OpenSavedDocument());
Henrique Nakashima8baea3c2017-11-10 20:27:23 +00001174 page = LoadSavedPage(0);
Lei Zhang4f556b82019-04-08 16:32:41 +00001175 VerifySavedRendering(page, 595, 842, kMd5);
Lei Zhanga21d5932018-02-05 18:28:38 +00001176 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001177 ScopedFPDFAnnotation new_annot(FPDFPage_GetAnnot(page, 0));
Jane Liu2e1a32b2017-07-06 12:01:25 -04001178
Lei Zhanga21d5932018-02-05 18:28:38 +00001179 // Check that the string value of the modified date is the newly-set value.
1180 EXPECT_EQ(FPDF_OBJECT_STRING,
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001181 FPDFAnnot_GetValueType(new_annot.get(), pdfium::annotation::kM));
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001182 unsigned long length_bytes = FPDFAnnot_GetStringValue(
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001183 new_annot.get(), pdfium::annotation::kM, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001184 ASSERT_EQ(44u, length_bytes);
1185 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001186 EXPECT_EQ(44u,
1187 FPDFAnnot_GetStringValue(new_annot.get(), pdfium::annotation::kM,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001188 buf.data(), length_bytes));
1189 EXPECT_EQ(kNewDate, GetPlatformWString(buf.data()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001190 }
Jane Liu2e1a32b2017-07-06 12:01:25 -04001191
Henrique Nakashima8baea3c2017-11-10 20:27:23 +00001192 CloseSavedPage(page);
Dan Sinclair04e4dc82017-10-18 12:17:14 -04001193 CloseSavedDocument();
Jane Liu2e1a32b2017-07-06 12:01:25 -04001194}
Diana Gage7e0c05d2017-07-19 17:33:33 -07001195
rycsmith3e785602019-03-05 21:48:36 +00001196TEST_F(FPDFAnnotEmbedderTest, GetNumberValue) {
1197 // Open a file with three text annotations and load its first page.
1198 ASSERT_TRUE(OpenDocument("text_form_multiple.pdf"));
1199 FPDF_PAGE page = LoadPage(0);
1200 ASSERT_TRUE(page);
1201 {
1202 // First two annotations do not have "MaxLen" attribute.
1203 for (int i = 0; i < 2; i++) {
1204 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, i));
1205 ASSERT_TRUE(annot);
1206
1207 // Verify that no "MaxLen" key present.
1208 EXPECT_FALSE(FPDFAnnot_HasKey(annot.get(), "MaxLen"));
1209
1210 float value;
1211 EXPECT_FALSE(FPDFAnnot_GetNumberValue(annot.get(), "MaxLen", &value));
1212 }
1213
1214 // Annotation in index 2 has "MaxLen" of 10.
1215 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
1216 ASSERT_TRUE(annot);
1217
1218 // Verify that "MaxLen" key present.
1219 EXPECT_TRUE(FPDFAnnot_HasKey(annot.get(), "MaxLen"));
1220
1221 float value;
1222 EXPECT_TRUE(FPDFAnnot_GetNumberValue(annot.get(), "MaxLen", &value));
1223 EXPECT_FLOAT_EQ(10.0f, value);
1224
1225 // Check bad inputs.
1226 EXPECT_FALSE(FPDFAnnot_GetNumberValue(nullptr, "MaxLen", &value));
1227 EXPECT_FALSE(FPDFAnnot_GetNumberValue(annot.get(), nullptr, &value));
1228 EXPECT_FALSE(FPDFAnnot_GetNumberValue(annot.get(), "MaxLen", nullptr));
1229 // Ask for key that exists but is not a number.
1230 EXPECT_FALSE(FPDFAnnot_GetNumberValue(annot.get(), "V", &value));
1231 }
1232
1233 UnloadPage(page);
1234}
1235
Lei Zhangab41f252018-12-23 03:10:50 +00001236TEST_F(FPDFAnnotEmbedderTest, GetSetAP) {
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001237 // Open a file with four annotations and load its first page.
1238 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001239 FPDF_PAGE page = LoadPage(0);
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001240 ASSERT_TRUE(page);
1241
Lei Zhanga21d5932018-02-05 18:28:38 +00001242 {
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001243 static const char kMd5NormalAP[] = "be903df0343fd774fadab9c8900cdf4a";
1244 static constexpr size_t kExpectNormalAPLength = 73970;
1245
Lei Zhanga21d5932018-02-05 18:28:38 +00001246 // Retrieve the first annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001247 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001248 ASSERT_TRUE(annot);
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001249
Lei Zhanga21d5932018-02-05 18:28:38 +00001250 // Check that the string value of an AP returns the expected length.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001251 unsigned long normal_length_bytes = FPDFAnnot_GetAP(
Lei Zhanga21d5932018-02-05 18:28:38 +00001252 annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001253 ASSERT_EQ(kExpectNormalAPLength, normal_length_bytes);
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001254
Lei Zhanga21d5932018-02-05 18:28:38 +00001255 // Check that the string value of an AP is not returned if the buffer is too
1256 // small. The result buffer should be overwritten with an empty string.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001257 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(normal_length_bytes);
1258 // Write in the buffer to verify it's not overwritten.
1259 memcpy(buf.data(), "abcdefgh", 8);
1260 EXPECT_EQ(kExpectNormalAPLength,
Lei Zhanga21d5932018-02-05 18:28:38 +00001261 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001262 buf.data(), normal_length_bytes - 1));
1263 EXPECT_EQ(0, memcmp(buf.data(), "abcdefgh", 8));
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001264
Lei Zhanga21d5932018-02-05 18:28:38 +00001265 // Check that the string value of an AP is returned through a buffer that is
1266 // the right size.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001267 EXPECT_EQ(kExpectNormalAPLength,
Lei Zhanga21d5932018-02-05 18:28:38 +00001268 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001269 buf.data(), normal_length_bytes));
1270 EXPECT_EQ(kMd5NormalAP,
1271 GenerateMD5Base16(reinterpret_cast<uint8_t*>(buf.data()),
1272 normal_length_bytes));
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001273
Lei Zhanga21d5932018-02-05 18:28:38 +00001274 // Check that the string value of an AP is returned through a buffer that is
1275 // larger than necessary.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001276 buf = GetFPDFWideStringBuffer(normal_length_bytes + 2);
1277 EXPECT_EQ(kExpectNormalAPLength,
Lei Zhanga21d5932018-02-05 18:28:38 +00001278 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001279 buf.data(), normal_length_bytes + 2));
1280 EXPECT_EQ(kMd5NormalAP,
1281 GenerateMD5Base16(reinterpret_cast<uint8_t*>(buf.data()),
1282 normal_length_bytes));
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001283
Lei Zhanga21d5932018-02-05 18:28:38 +00001284 // Check that getting an AP for a mode that does not have an AP returns an
1285 // empty string.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001286 unsigned long rollover_length_bytes = FPDFAnnot_GetAP(
Lei Zhanga21d5932018-02-05 18:28:38 +00001287 annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001288 ASSERT_EQ(2u, rollover_length_bytes);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001289
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001290 buf = GetFPDFWideStringBuffer(1000);
Lei Zhanga21d5932018-02-05 18:28:38 +00001291 EXPECT_EQ(2u,
1292 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001293 buf.data(), 1000));
1294 EXPECT_EQ(L"", GetPlatformWString(buf.data()));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001295
Lei Zhanga21d5932018-02-05 18:28:38 +00001296 // Check that setting the AP for an invalid appearance mode fails.
Lei Zhangf0f67682019-04-08 17:03:21 +00001297 ScopedFPDFWideString ap_text = GetFPDFWideString(L"new test ap");
Lei Zhang4f556b82019-04-08 16:32:41 +00001298 EXPECT_FALSE(FPDFAnnot_SetAP(annot.get(), -1, ap_text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001299 EXPECT_FALSE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_COUNT,
Lei Zhang4f556b82019-04-08 16:32:41 +00001300 ap_text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001301 EXPECT_FALSE(FPDFAnnot_SetAP(
Lei Zhang4f556b82019-04-08 16:32:41 +00001302 annot.get(), FPDF_ANNOT_APPEARANCEMODE_COUNT + 1, ap_text.get()));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001303
Lei Zhanga21d5932018-02-05 18:28:38 +00001304 // Set the AP correctly now.
1305 EXPECT_TRUE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang4f556b82019-04-08 16:32:41 +00001306 ap_text.get()));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001307
Lei Zhanga21d5932018-02-05 18:28:38 +00001308 // Check that the new annotation value is equal to the value we just set.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001309 rollover_length_bytes = FPDFAnnot_GetAP(
Lei Zhanga21d5932018-02-05 18:28:38 +00001310 annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001311 ASSERT_EQ(24u, rollover_length_bytes);
1312 buf = GetFPDFWideStringBuffer(rollover_length_bytes);
Lei Zhanga21d5932018-02-05 18:28:38 +00001313 EXPECT_EQ(24u,
1314 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001315 buf.data(), rollover_length_bytes));
1316 EXPECT_EQ(L"new test ap", GetPlatformWString(buf.data()));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001317
Lei Zhanga21d5932018-02-05 18:28:38 +00001318 // Check that the Normal AP was not touched when the Rollover AP was set.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001319 buf = GetFPDFWideStringBuffer(normal_length_bytes);
1320 EXPECT_EQ(kExpectNormalAPLength,
Lei Zhanga21d5932018-02-05 18:28:38 +00001321 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001322 buf.data(), normal_length_bytes));
1323 EXPECT_EQ(kMd5NormalAP,
1324 GenerateMD5Base16(reinterpret_cast<uint8_t*>(buf.data()),
1325 normal_length_bytes));
Lei Zhanga21d5932018-02-05 18:28:38 +00001326 }
Henrique Nakashima5970a472018-01-11 22:40:59 +00001327
1328 // Save the modified document, then reopen it.
Henrique Nakashima5970a472018-01-11 22:40:59 +00001329 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang75c81712018-02-08 17:22:39 +00001330 UnloadPage(page);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001331
Lei Zhang0b494052019-01-31 21:41:15 +00001332 ASSERT_TRUE(OpenSavedDocument());
Henrique Nakashima5970a472018-01-11 22:40:59 +00001333 page = LoadSavedPage(0);
Lei Zhanga21d5932018-02-05 18:28:38 +00001334 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001335 ScopedFPDFAnnotation new_annot(FPDFPage_GetAnnot(page, 0));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001336
Lei Zhanga21d5932018-02-05 18:28:38 +00001337 // Check that the new annotation value is equal to the value we set before
1338 // saving.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001339 unsigned long rollover_length_bytes = FPDFAnnot_GetAP(
Lei Zhanga21d5932018-02-05 18:28:38 +00001340 new_annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001341 ASSERT_EQ(24u, rollover_length_bytes);
1342 std::vector<FPDF_WCHAR> buf =
1343 GetFPDFWideStringBuffer(rollover_length_bytes);
Lei Zhanga21d5932018-02-05 18:28:38 +00001344 EXPECT_EQ(24u, FPDFAnnot_GetAP(new_annot.get(),
1345 FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001346 buf.data(), rollover_length_bytes));
1347 EXPECT_EQ(L"new test ap", GetPlatformWString(buf.data()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001348 }
Henrique Nakashima5970a472018-01-11 22:40:59 +00001349
1350 // Close saved document.
Henrique Nakashima5970a472018-01-11 22:40:59 +00001351 CloseSavedPage(page);
1352 CloseSavedDocument();
1353}
1354
Lei Zhangab41f252018-12-23 03:10:50 +00001355TEST_F(FPDFAnnotEmbedderTest, RemoveOptionalAP) {
Henrique Nakashima5970a472018-01-11 22:40:59 +00001356 // Open a file with four annotations and load its first page.
1357 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001358 FPDF_PAGE page = LoadPage(0);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001359 ASSERT_TRUE(page);
1360
Lei Zhanga21d5932018-02-05 18:28:38 +00001361 {
1362 // Retrieve the first annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001363 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001364 ASSERT_TRUE(annot);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001365
Lei Zhanga21d5932018-02-05 18:28:38 +00001366 // Set Down AP. Normal AP is already set.
Lei Zhangf0f67682019-04-08 17:03:21 +00001367 ScopedFPDFWideString ap_text = GetFPDFWideString(L"new test ap");
Lei Zhanga21d5932018-02-05 18:28:38 +00001368 EXPECT_TRUE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
Lei Zhang4f556b82019-04-08 16:32:41 +00001369 ap_text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001370 EXPECT_EQ(73970u,
1371 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
1372 nullptr, 0));
1373 EXPECT_EQ(24u, FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
1374 nullptr, 0));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001375
Lei Zhanga21d5932018-02-05 18:28:38 +00001376 // Check that setting the Down AP to null removes the Down entry but keeps
1377 // Normal intact.
1378 EXPECT_TRUE(
1379 FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN, nullptr));
1380 EXPECT_EQ(73970u,
1381 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
1382 nullptr, 0));
1383 EXPECT_EQ(2u, FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
1384 nullptr, 0));
1385 }
Henrique Nakashima5970a472018-01-11 22:40:59 +00001386
Lei Zhang75c81712018-02-08 17:22:39 +00001387 UnloadPage(page);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001388}
1389
Lei Zhangab41f252018-12-23 03:10:50 +00001390TEST_F(FPDFAnnotEmbedderTest, RemoveRequiredAP) {
Henrique Nakashima5970a472018-01-11 22:40:59 +00001391 // Open a file with four annotations and load its first page.
1392 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001393 FPDF_PAGE page = LoadPage(0);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001394 ASSERT_TRUE(page);
1395
Lei Zhanga21d5932018-02-05 18:28:38 +00001396 {
1397 // Retrieve the first annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001398 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001399 ASSERT_TRUE(annot);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001400
Lei Zhanga21d5932018-02-05 18:28:38 +00001401 // Set Down AP. Normal AP is already set.
Lei Zhangf0f67682019-04-08 17:03:21 +00001402 ScopedFPDFWideString ap_text = GetFPDFWideString(L"new test ap");
Lei Zhanga21d5932018-02-05 18:28:38 +00001403 EXPECT_TRUE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
Lei Zhang4f556b82019-04-08 16:32:41 +00001404 ap_text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001405 EXPECT_EQ(73970u,
1406 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
1407 nullptr, 0));
1408 EXPECT_EQ(24u, FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
1409 nullptr, 0));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001410
Lei Zhanga21d5932018-02-05 18:28:38 +00001411 // Check that setting the Normal AP to null removes the whole AP dictionary.
1412 EXPECT_TRUE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
1413 nullptr));
1414 EXPECT_EQ(2u, FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
1415 nullptr, 0));
1416 EXPECT_EQ(2u, FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
1417 nullptr, 0));
1418 }
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001419
Lei Zhang75c81712018-02-08 17:22:39 +00001420 UnloadPage(page);
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001421}
1422
Lei Zhangab41f252018-12-23 03:10:50 +00001423TEST_F(FPDFAnnotEmbedderTest, ExtractLinkedAnnotations) {
Jane Liu300bb272017-08-21 14:37:53 -04001424 // Open a file with annotations and load its first page.
1425 ASSERT_TRUE(OpenDocument("annotation_highlight_square_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001426 FPDF_PAGE page = LoadPage(0);
Jane Liu300bb272017-08-21 14:37:53 -04001427 ASSERT_TRUE(page);
Jane Liud1ed1ce2017-08-24 12:31:10 -04001428 EXPECT_EQ(-1, FPDFPage_GetAnnotIndex(page, nullptr));
Jane Liu300bb272017-08-21 14:37:53 -04001429
Lei Zhanga21d5932018-02-05 18:28:38 +00001430 {
1431 // Retrieve the highlight annotation which has its popup defined.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001432 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001433 ASSERT_TRUE(annot);
1434 EXPECT_EQ(FPDF_ANNOT_HIGHLIGHT, FPDFAnnot_GetSubtype(annot.get()));
1435 EXPECT_EQ(0, FPDFPage_GetAnnotIndex(page, annot.get()));
Lei Zhang4f556b82019-04-08 16:32:41 +00001436 static const char kPopupKey[] = "Popup";
Lei Zhanga21d5932018-02-05 18:28:38 +00001437 ASSERT_TRUE(FPDFAnnot_HasKey(annot.get(), kPopupKey));
1438 ASSERT_EQ(FPDF_OBJECT_REFERENCE,
1439 FPDFAnnot_GetValueType(annot.get(), kPopupKey));
Jane Liu300bb272017-08-21 14:37:53 -04001440
Lei Zhanga21d5932018-02-05 18:28:38 +00001441 // Retrieve and verify the popup of the highlight annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001442 ScopedFPDFAnnotation popup(
Lei Zhanga21d5932018-02-05 18:28:38 +00001443 FPDFAnnot_GetLinkedAnnot(annot.get(), kPopupKey));
1444 ASSERT_TRUE(popup);
1445 EXPECT_EQ(FPDF_ANNOT_POPUP, FPDFAnnot_GetSubtype(popup.get()));
1446 EXPECT_EQ(1, FPDFPage_GetAnnotIndex(page, popup.get()));
1447 FS_RECTF rect;
1448 ASSERT_TRUE(FPDFAnnot_GetRect(popup.get(), &rect));
1449 EXPECT_NEAR(612.0f, rect.left, 0.001f);
1450 EXPECT_NEAR(578.792, rect.bottom, 0.001f);
Jane Liu300bb272017-08-21 14:37:53 -04001451
Lei Zhanga21d5932018-02-05 18:28:38 +00001452 // Attempting to retrieve |annot|'s "IRT"-linked annotation would fail,
1453 // since "IRT" is not a key in |annot|'s dictionary.
Lei Zhang4f556b82019-04-08 16:32:41 +00001454 static const char kIRTKey[] = "IRT";
Lei Zhanga21d5932018-02-05 18:28:38 +00001455 ASSERT_FALSE(FPDFAnnot_HasKey(annot.get(), kIRTKey));
1456 EXPECT_FALSE(FPDFAnnot_GetLinkedAnnot(annot.get(), kIRTKey));
Jane Liu300bb272017-08-21 14:37:53 -04001457
Lei Zhanga21d5932018-02-05 18:28:38 +00001458 // Attempting to retrieve |annot|'s parent dictionary as an annotation
1459 // would fail, since its parent is not an annotation.
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001460 ASSERT_TRUE(FPDFAnnot_HasKey(annot.get(), pdfium::annotation::kP));
Lei Zhanga21d5932018-02-05 18:28:38 +00001461 EXPECT_EQ(FPDF_OBJECT_REFERENCE,
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001462 FPDFAnnot_GetValueType(annot.get(), pdfium::annotation::kP));
1463 EXPECT_FALSE(FPDFAnnot_GetLinkedAnnot(annot.get(), pdfium::annotation::kP));
Lei Zhanga21d5932018-02-05 18:28:38 +00001464 }
Jane Liu300bb272017-08-21 14:37:53 -04001465
Jane Liu300bb272017-08-21 14:37:53 -04001466 UnloadPage(page);
1467}
1468
Lei Zhangab41f252018-12-23 03:10:50 +00001469TEST_F(FPDFAnnotEmbedderTest, GetFormFieldFlagsTextField) {
Diana Gage7e0c05d2017-07-19 17:33:33 -07001470 // Open file with form text fields.
1471 ASSERT_TRUE(OpenDocument("text_form_multiple.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001472 FPDF_PAGE page = LoadPage(0);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001473 ASSERT_TRUE(page);
1474
Lei Zhanga21d5932018-02-05 18:28:38 +00001475 {
1476 // Retrieve the first annotation: user-editable text field.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001477 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001478 ASSERT_TRUE(annot);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001479
Lei Zhanga21d5932018-02-05 18:28:38 +00001480 // Check that the flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001481 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001482 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1483 }
Diana Gage7e0c05d2017-07-19 17:33:33 -07001484
Lei Zhanga21d5932018-02-05 18:28:38 +00001485 {
1486 // Retrieve the second annotation: read-only text field.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001487 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 1));
Lei Zhanga21d5932018-02-05 18:28:38 +00001488 ASSERT_TRUE(annot);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001489
Lei Zhanga21d5932018-02-05 18:28:38 +00001490 // Check that the flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001491 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001492 EXPECT_TRUE(flags & FPDF_FORMFLAG_READONLY);
1493 }
Diana Gage7e0c05d2017-07-19 17:33:33 -07001494
1495 UnloadPage(page);
1496}
1497
Lei Zhangab41f252018-12-23 03:10:50 +00001498TEST_F(FPDFAnnotEmbedderTest, GetFormFieldFlagsComboBox) {
Diana Gage7e0c05d2017-07-19 17:33:33 -07001499 // Open file with form text fields.
1500 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001501 FPDF_PAGE page = LoadPage(0);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001502 ASSERT_TRUE(page);
1503
Lei Zhanga21d5932018-02-05 18:28:38 +00001504 {
1505 // Retrieve the first annotation: user-editable combobox.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001506 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001507 ASSERT_TRUE(annot);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001508
Lei Zhanga21d5932018-02-05 18:28:38 +00001509 // Check that the flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001510 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001511 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1512 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1513 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1514 }
Diana Gage7e0c05d2017-07-19 17:33:33 -07001515
Lei Zhanga21d5932018-02-05 18:28:38 +00001516 {
1517 // Retrieve the second annotation: regular combobox.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001518 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 1));
Lei Zhanga21d5932018-02-05 18:28:38 +00001519 ASSERT_TRUE(annot);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001520
Lei Zhanga21d5932018-02-05 18:28:38 +00001521 // Check that the flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001522 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001523 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1524 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1525 EXPECT_FALSE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1526 }
Diana Gage7e0c05d2017-07-19 17:33:33 -07001527
Lei Zhanga21d5932018-02-05 18:28:38 +00001528 {
1529 // Retrieve the third annotation: read-only combobox.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001530 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +00001531 ASSERT_TRUE(annot);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001532
Lei Zhanga21d5932018-02-05 18:28:38 +00001533 // Check that the flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001534 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001535 EXPECT_TRUE(flags & FPDF_FORMFLAG_READONLY);
1536 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1537 EXPECT_FALSE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1538 }
Diana Gage7e0c05d2017-07-19 17:33:33 -07001539
1540 UnloadPage(page);
1541}
Diana Gage40870db2017-07-19 18:16:03 -07001542
Lei Zhangab41f252018-12-23 03:10:50 +00001543TEST_F(FPDFAnnotEmbedderTest, GetFormAnnotNull) {
Diana Gage40870db2017-07-19 18:16:03 -07001544 // Open file with form text fields.
1545 EXPECT_TRUE(OpenDocument("text_form.pdf"));
1546 FPDF_PAGE page = LoadPage(0);
1547 ASSERT_TRUE(page);
1548
1549 // Attempt to get an annotation where no annotation exists on page.
Lei Zhang7557e7b2018-09-14 17:02:40 +00001550 EXPECT_FALSE(FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 0, 0));
1551
1552 {
1553 // Verify there is an annotation.
1554 ScopedFPDFAnnotation annot(
1555 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 120, 120));
1556 EXPECT_TRUE(annot);
1557 }
1558
1559 // Try other bad inputs at a valid location.
1560 EXPECT_FALSE(FPDFAnnot_GetFormFieldAtPoint(nullptr, nullptr, 120, 120));
1561 EXPECT_FALSE(FPDFAnnot_GetFormFieldAtPoint(nullptr, page, 120, 120));
1562 EXPECT_FALSE(FPDFAnnot_GetFormFieldAtPoint(form_handle(), nullptr, 120, 120));
Diana Gage40870db2017-07-19 18:16:03 -07001563
1564 UnloadPage(page);
1565}
1566
Lei Zhangab41f252018-12-23 03:10:50 +00001567TEST_F(FPDFAnnotEmbedderTest, GetFormAnnotAndCheckFlagsTextField) {
Diana Gage40870db2017-07-19 18:16:03 -07001568 // Open file with form text fields.
1569 EXPECT_TRUE(OpenDocument("text_form_multiple.pdf"));
1570 FPDF_PAGE page = LoadPage(0);
1571 ASSERT_TRUE(page);
1572
Lei Zhanga21d5932018-02-05 18:28:38 +00001573 {
1574 // Retrieve user-editable text field annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001575 ScopedFPDFAnnotation annot(
Lei Zhanga21d5932018-02-05 18:28:38 +00001576 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 105, 118));
1577 ASSERT_TRUE(annot);
Diana Gage40870db2017-07-19 18:16:03 -07001578
Lei Zhanga21d5932018-02-05 18:28:38 +00001579 // Check that interactive form annotation flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001580 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001581 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1582 }
Diana Gage40870db2017-07-19 18:16:03 -07001583
Lei Zhanga21d5932018-02-05 18:28:38 +00001584 {
1585 // Retrieve read-only text field annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001586 ScopedFPDFAnnotation annot(
Lei Zhanga21d5932018-02-05 18:28:38 +00001587 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 105, 202));
1588 ASSERT_TRUE(annot);
Diana Gage40870db2017-07-19 18:16:03 -07001589
Lei Zhanga21d5932018-02-05 18:28:38 +00001590 // Check that interactive form annotation flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001591 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001592 EXPECT_TRUE(flags & FPDF_FORMFLAG_READONLY);
1593 }
Diana Gage40870db2017-07-19 18:16:03 -07001594
1595 UnloadPage(page);
1596}
1597
Lei Zhangab41f252018-12-23 03:10:50 +00001598TEST_F(FPDFAnnotEmbedderTest, GetFormAnnotAndCheckFlagsComboBox) {
Diana Gage40870db2017-07-19 18:16:03 -07001599 // Open file with form comboboxes.
1600 EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
1601 FPDF_PAGE page = LoadPage(0);
1602 ASSERT_TRUE(page);
1603
Lei Zhanga21d5932018-02-05 18:28:38 +00001604 {
1605 // Retrieve user-editable combobox annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001606 ScopedFPDFAnnotation annot(
Henrique Nakashima20830922018-03-19 21:21:46 +00001607 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 102, 363));
Lei Zhanga21d5932018-02-05 18:28:38 +00001608 ASSERT_TRUE(annot);
Diana Gage40870db2017-07-19 18:16:03 -07001609
Lei Zhanga21d5932018-02-05 18:28:38 +00001610 // Check that interactive form annotation flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001611 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001612 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1613 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1614 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1615 }
Diana Gage40870db2017-07-19 18:16:03 -07001616
Lei Zhanga21d5932018-02-05 18:28:38 +00001617 {
1618 // Retrieve regular combobox annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001619 ScopedFPDFAnnotation annot(
Henrique Nakashima20830922018-03-19 21:21:46 +00001620 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 102, 413));
Lei Zhanga21d5932018-02-05 18:28:38 +00001621 ASSERT_TRUE(annot);
Diana Gage40870db2017-07-19 18:16:03 -07001622
Lei Zhanga21d5932018-02-05 18:28:38 +00001623 // Check that interactive form annotation flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001624 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001625 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1626 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1627 EXPECT_FALSE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1628 }
Diana Gage40870db2017-07-19 18:16:03 -07001629
Lei Zhanga21d5932018-02-05 18:28:38 +00001630 {
1631 // Retrieve read-only combobox annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001632 ScopedFPDFAnnotation annot(
Henrique Nakashima20830922018-03-19 21:21:46 +00001633 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 102, 513));
Lei Zhanga21d5932018-02-05 18:28:38 +00001634 ASSERT_TRUE(annot);
Diana Gage40870db2017-07-19 18:16:03 -07001635
Lei Zhanga21d5932018-02-05 18:28:38 +00001636 // Check that interactive form annotation flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001637 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001638 EXPECT_TRUE(flags & FPDF_FORMFLAG_READONLY);
1639 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1640 EXPECT_FALSE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1641 }
Diana Gage40870db2017-07-19 18:16:03 -07001642
1643 UnloadPage(page);
1644}
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001645
Lei Zhang03e5e682019-09-16 19:45:55 +00001646// TODO(crbug.com/pdfium/11): Fix this test and enable.
1647#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
1648#define MAYBE_BUG_1206 DISABLED_BUG_1206
1649#else
1650#define MAYBE_BUG_1206 BUG_1206
1651#endif
1652TEST_F(FPDFAnnotEmbedderTest, MAYBE_BUG_1206) {
Lei Zhang992e7e22019-02-04 19:20:58 +00001653 static constexpr size_t kExpectedSize = 1609;
1654 static const char kExpectedBitmap[] = "0d9fc05c6762fd788bd23fd87a4967bc";
1655
1656 ASSERT_TRUE(OpenDocument("bug_1206.pdf"));
1657
1658 FPDF_PAGE page = LoadPage(0);
1659 ASSERT_TRUE(page);
1660
1661 ASSERT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
1662 EXPECT_EQ(kExpectedSize, GetString().size());
1663 ClearString();
1664
1665 for (size_t i = 0; i < 10; ++i) {
1666 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
1667 CompareBitmap(bitmap.get(), 612, 792, kExpectedBitmap);
1668
1669 ASSERT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
1670 // TODO(https://crbug.com/pdfium/1206): This is wrong. The size should be
1671 // equal, not bigger.
1672 EXPECT_LT(kExpectedSize, GetString().size());
1673 ClearString();
1674 }
1675
1676 UnloadPage(page);
1677}
1678
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001679TEST_F(FPDFAnnotEmbedderTest, BUG_1212) {
1680 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
1681 FPDF_PAGE page = LoadPage(0);
1682 ASSERT_TRUE(page);
1683 EXPECT_EQ(0, FPDFPage_GetAnnotCount(page));
1684
1685 static const char kTestKey[] = "test";
Lei Zhang4f556b82019-04-08 16:32:41 +00001686 static const wchar_t kData[] = L"\xf6\xe4";
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001687 static const size_t kBufSize = 12;
1688 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(kBufSize);
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001689
1690 {
1691 // Add a text annotation to the page.
1692 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_TEXT));
1693 ASSERT_TRUE(annot);
1694 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
1695 EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
1696
1697 // Make sure there is no test key, add set a value there, and read it back.
1698 std::fill(buf.begin(), buf.end(), 'x');
1699 ASSERT_EQ(2u, FPDFAnnot_GetStringValue(annot.get(), kTestKey, buf.data(),
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001700 kBufSize));
1701 EXPECT_EQ(L"", GetPlatformWString(buf.data()));
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001702
Lei Zhangf0f67682019-04-08 17:03:21 +00001703 ScopedFPDFWideString text = GetFPDFWideString(kData);
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001704 EXPECT_TRUE(FPDFAnnot_SetStringValue(annot.get(), kTestKey, text.get()));
1705
1706 std::fill(buf.begin(), buf.end(), 'x');
1707 ASSERT_EQ(6u, FPDFAnnot_GetStringValue(annot.get(), kTestKey, buf.data(),
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001708 kBufSize));
1709 EXPECT_EQ(kData, GetPlatformWString(buf.data()));
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001710 }
1711
Lei Zhang05ec64c2019-01-09 03:00:06 +00001712 {
1713 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP));
1714 ASSERT_TRUE(annot);
1715 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
1716 EXPECT_EQ(FPDF_ANNOT_STAMP, FPDFAnnot_GetSubtype(annot.get()));
1717 // Also do the same test for its appearance string.
1718 std::fill(buf.begin(), buf.end(), 'x');
1719 ASSERT_EQ(2u,
1720 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001721 buf.data(), kBufSize));
1722 EXPECT_EQ(L"", GetPlatformWString(buf.data()));
Lei Zhang05ec64c2019-01-09 03:00:06 +00001723
Lei Zhangf0f67682019-04-08 17:03:21 +00001724 ScopedFPDFWideString text = GetFPDFWideString(kData);
Lei Zhang05ec64c2019-01-09 03:00:06 +00001725 EXPECT_TRUE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
1726 text.get()));
1727
1728 std::fill(buf.begin(), buf.end(), 'x');
1729 ASSERT_EQ(6u,
1730 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001731 buf.data(), kBufSize));
1732 EXPECT_EQ(kData, GetPlatformWString(buf.data()));
Lei Zhang05ec64c2019-01-09 03:00:06 +00001733 }
1734
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001735 UnloadPage(page);
1736
1737 {
1738 // Save a copy, open the copy, and check the annotation again.
1739 // Note that it renders the rotation.
1740 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang0b494052019-01-31 21:41:15 +00001741 ASSERT_TRUE(OpenSavedDocument());
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001742 FPDF_PAGE saved_page = LoadSavedPage(0);
1743 ASSERT_TRUE(saved_page);
1744
Lei Zhang05ec64c2019-01-09 03:00:06 +00001745 EXPECT_EQ(2, FPDFPage_GetAnnotCount(saved_page));
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001746 {
1747 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(saved_page, 0));
1748 ASSERT_TRUE(annot);
1749 EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
1750
1751 std::fill(buf.begin(), buf.end(), 'x');
1752 ASSERT_EQ(6u, FPDFAnnot_GetStringValue(annot.get(), kTestKey, buf.data(),
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001753 kBufSize));
1754 EXPECT_EQ(kData, GetPlatformWString(buf.data()));
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001755 }
1756
Lei Zhang05ec64c2019-01-09 03:00:06 +00001757 {
1758 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(saved_page, 0));
1759 ASSERT_TRUE(annot);
1760 // TODO(thestig): This return FPDF_ANNOT_UNKNOWN for some reason.
1761 // EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
1762
1763 std::fill(buf.begin(), buf.end(), 'x');
1764 ASSERT_EQ(6u, FPDFAnnot_GetStringValue(annot.get(), kTestKey, buf.data(),
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001765 kBufSize));
1766 EXPECT_EQ(kData, GetPlatformWString(buf.data()));
Lei Zhang05ec64c2019-01-09 03:00:06 +00001767 }
1768
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001769 CloseSavedPage(saved_page);
1770 CloseSavedDocument();
1771 }
1772}
rycsmithcb752f32019-02-21 18:40:53 +00001773
1774TEST_F(FPDFAnnotEmbedderTest, GetOptionCountCombobox) {
1775 // Open a file with combobox widget annotations and load its first page.
1776 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
1777 FPDF_PAGE page = LoadPage(0);
1778 ASSERT_TRUE(page);
1779
1780 {
1781 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1782 ASSERT_TRUE(annot);
1783
1784 EXPECT_EQ(3, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
1785
1786 annot.reset(FPDFPage_GetAnnot(page, 1));
1787 ASSERT_TRUE(annot);
1788
1789 EXPECT_EQ(26, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
Lei Zhange7033c82019-02-26 19:30:49 +00001790
1791 // Check bad form handle / annot.
1792 EXPECT_EQ(-1, FPDFAnnot_GetOptionCount(nullptr, nullptr));
1793 EXPECT_EQ(-1, FPDFAnnot_GetOptionCount(form_handle(), nullptr));
1794 EXPECT_EQ(-1, FPDFAnnot_GetOptionCount(nullptr, annot.get()));
rycsmithcb752f32019-02-21 18:40:53 +00001795 }
1796
1797 UnloadPage(page);
1798}
1799
1800TEST_F(FPDFAnnotEmbedderTest, GetOptionCountListbox) {
1801 // Open a file with listbox widget annotations and load its first page.
1802 ASSERT_TRUE(OpenDocument("listbox_form.pdf"));
1803 FPDF_PAGE page = LoadPage(0);
1804 ASSERT_TRUE(page);
1805
1806 {
1807 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1808 ASSERT_TRUE(annot);
1809
1810 EXPECT_EQ(3, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
1811
1812 annot.reset(FPDFPage_GetAnnot(page, 1));
1813 ASSERT_TRUE(annot);
1814
1815 EXPECT_EQ(26, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
1816 }
1817
1818 UnloadPage(page);
1819}
1820
1821TEST_F(FPDFAnnotEmbedderTest, GetOptionCountInvalidAnnotations) {
1822 // Open a file with ink annotations and load its first page.
1823 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
1824 FPDF_PAGE page = LoadPage(0);
1825 ASSERT_TRUE(page);
1826
1827 {
1828 // annotations do not have "Opt" array and will return -1
1829 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1830 ASSERT_TRUE(annot);
1831
1832 EXPECT_EQ(-1, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
1833
1834 annot.reset(FPDFPage_GetAnnot(page, 1));
1835 ASSERT_TRUE(annot);
1836
1837 EXPECT_EQ(-1, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
1838 }
1839
1840 UnloadPage(page);
1841}
1842
1843TEST_F(FPDFAnnotEmbedderTest, GetOptionLabelCombobox) {
1844 // Open a file with combobox widget annotations and load its first page.
1845 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
1846 FPDF_PAGE page = LoadPage(0);
1847 ASSERT_TRUE(page);
1848
1849 {
1850 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1851 ASSERT_TRUE(annot);
1852
1853 int index = 0;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001854 unsigned long length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001855 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001856 ASSERT_EQ(8u, length_bytes);
1857 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001858 EXPECT_EQ(8u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001859 buf.data(), length_bytes));
1860 EXPECT_EQ(L"Foo", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001861
1862 annot.reset(FPDFPage_GetAnnot(page, 1));
1863 ASSERT_TRUE(annot);
1864
1865 index = 0;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001866 length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001867 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001868 ASSERT_EQ(12u, length_bytes);
1869 buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001870 EXPECT_EQ(12u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001871 buf.data(), length_bytes));
1872 EXPECT_EQ(L"Apple", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001873
1874 index = 25;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001875 length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001876 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001877 buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001878 EXPECT_EQ(18u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001879 buf.data(), length_bytes));
1880 EXPECT_EQ(L"Zucchini", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001881
Lei Zhange7033c82019-02-26 19:30:49 +00001882 // Indices out of range
rycsmithcb752f32019-02-21 18:40:53 +00001883 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), -1,
1884 nullptr, 0));
1885 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), 26,
1886 nullptr, 0));
Lei Zhange7033c82019-02-26 19:30:49 +00001887
1888 // Check bad form handle / annot.
1889 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(nullptr, nullptr, 0, nullptr, 0));
1890 EXPECT_EQ(0u,
1891 FPDFAnnot_GetOptionLabel(nullptr, annot.get(), 0, nullptr, 0));
1892 EXPECT_EQ(0u,
1893 FPDFAnnot_GetOptionLabel(form_handle(), nullptr, 0, nullptr, 0));
rycsmithcb752f32019-02-21 18:40:53 +00001894 }
1895
1896 UnloadPage(page);
1897}
1898
1899TEST_F(FPDFAnnotEmbedderTest, GetOptionLabelListbox) {
1900 // Open a file with listbox widget annotations and load its first page.
1901 ASSERT_TRUE(OpenDocument("listbox_form.pdf"));
1902 FPDF_PAGE page = LoadPage(0);
1903 ASSERT_TRUE(page);
1904
1905 {
1906 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1907 ASSERT_TRUE(annot);
1908
1909 int index = 0;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001910 unsigned long length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001911 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001912 ASSERT_EQ(8u, length_bytes);
1913 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001914 EXPECT_EQ(8u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001915 buf.data(), length_bytes));
1916 EXPECT_EQ(L"Foo", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001917
1918 annot.reset(FPDFPage_GetAnnot(page, 1));
1919 ASSERT_TRUE(annot);
1920
1921 index = 0;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001922 length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001923 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001924 ASSERT_EQ(12u, length_bytes);
1925 buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001926 EXPECT_EQ(12u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001927 buf.data(), length_bytes));
1928 EXPECT_EQ(L"Apple", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001929
1930 index = 25;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001931 length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001932 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001933 ASSERT_EQ(18u, length_bytes);
1934 buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001935 EXPECT_EQ(18u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001936 buf.data(), length_bytes));
1937 EXPECT_EQ(L"Zucchini", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001938
1939 // indices out of range
1940 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), -1,
1941 nullptr, 0));
1942 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), 26,
1943 nullptr, 0));
1944 }
1945
1946 UnloadPage(page);
1947}
1948
1949TEST_F(FPDFAnnotEmbedderTest, GetOptionLabelInvalidAnnotations) {
1950 // Open a file with ink annotations and load its first page.
1951 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
1952 FPDF_PAGE page = LoadPage(0);
1953 ASSERT_TRUE(page);
1954
1955 {
1956 // annotations do not have "Opt" array and will return 0
1957 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1958 ASSERT_TRUE(annot);
1959
1960 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), 0,
1961 nullptr, 0));
1962
1963 annot.reset(FPDFPage_GetAnnot(page, 1));
1964 ASSERT_TRUE(annot);
1965
1966 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), 0,
1967 nullptr, 0));
1968 }
1969
1970 UnloadPage(page);
1971}
Ryan Smith09c23b12019-04-25 18:09:06 +00001972
1973TEST_F(FPDFAnnotEmbedderTest, GetFontSizeCombobox) {
1974 // Open a file with combobox annotations and load its first page.
1975 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
1976 FPDF_PAGE page = LoadPage(0);
1977 ASSERT_TRUE(page);
1978
1979 {
1980 // All 3 widgets have Tf font size 12.
1981 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1982 ASSERT_TRUE(annot);
1983
1984 float value;
1985 ASSERT_TRUE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value));
1986 EXPECT_EQ(12.0, value);
1987
1988 annot.reset(FPDFPage_GetAnnot(page, 1));
1989 ASSERT_TRUE(annot);
1990
1991 float value_two;
1992 ASSERT_TRUE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value_two));
1993 EXPECT_EQ(12.0, value_two);
1994
1995 annot.reset(FPDFPage_GetAnnot(page, 2));
1996 ASSERT_TRUE(annot);
1997
1998 float value_three;
1999 ASSERT_TRUE(
2000 FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value_three));
2001 EXPECT_EQ(12.0, value_three);
2002 }
2003
2004 UnloadPage(page);
2005}
2006
2007TEST_F(FPDFAnnotEmbedderTest, GetFontSizeTextField) {
2008 // Open a file with textfield annotations and load its first page.
2009 ASSERT_TRUE(OpenDocument("text_form_multiple.pdf"));
2010 FPDF_PAGE page = LoadPage(0);
2011 ASSERT_TRUE(page);
2012
2013 {
2014 // All 3 widgets have Tf font size 12.
2015 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2016 ASSERT_TRUE(annot);
2017
2018 float value;
2019 ASSERT_TRUE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value));
2020 EXPECT_EQ(12.0, value);
2021
2022 annot.reset(FPDFPage_GetAnnot(page, 1));
2023 ASSERT_TRUE(annot);
2024
2025 float value_two;
2026 ASSERT_TRUE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value_two));
2027 EXPECT_EQ(12.0, value_two);
2028
2029 annot.reset(FPDFPage_GetAnnot(page, 2));
2030 ASSERT_TRUE(annot);
2031
2032 float value_three;
2033 ASSERT_TRUE(
2034 FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value_three));
2035 EXPECT_EQ(12.0, value_three);
2036 }
2037
2038 UnloadPage(page);
2039}
2040
2041TEST_F(FPDFAnnotEmbedderTest, GetFontSizeInvalidAnnotationTypes) {
2042 // Open a file with ink annotations and load its first page.
2043 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
2044 FPDF_PAGE page = LoadPage(0);
2045 ASSERT_TRUE(page);
2046
2047 {
2048 // Annotations that do not have variable text and will return -1.
2049 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2050 ASSERT_TRUE(annot);
2051
2052 float value;
2053 ASSERT_FALSE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value));
2054
2055 annot.reset(FPDFPage_GetAnnot(page, 1));
2056 ASSERT_TRUE(annot);
2057
2058 ASSERT_FALSE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value));
2059 }
2060
2061 UnloadPage(page);
2062}
2063
2064TEST_F(FPDFAnnotEmbedderTest, GetFontSizeInvalidArguments) {
2065 // Open a file with combobox annotations and load its first page.
2066 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
2067 FPDF_PAGE page = LoadPage(0);
2068 ASSERT_TRUE(page);
2069
2070 {
2071 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2072 ASSERT_TRUE(annot);
2073
2074 // Check bad form handle / annot.
2075 float value;
2076 ASSERT_FALSE(FPDFAnnot_GetFontSize(nullptr, annot.get(), &value));
2077 ASSERT_FALSE(FPDFAnnot_GetFontSize(form_handle(), nullptr, &value));
2078 ASSERT_FALSE(FPDFAnnot_GetFontSize(nullptr, nullptr, &value));
2079 }
2080
2081 UnloadPage(page);
2082}
2083
2084TEST_F(FPDFAnnotEmbedderTest, GetFontSizeNegative) {
2085 // Open a file with textfield annotations and load its first page.
2086 ASSERT_TRUE(OpenDocument("text_form_negative_fontsize.pdf"));
2087 FPDF_PAGE page = LoadPage(0);
2088 ASSERT_TRUE(page);
2089
2090 {
2091 // Obtain the first annotation, a text field with negative font size, -12.
2092 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2093 ASSERT_TRUE(annot);
2094
2095 float value;
2096 ASSERT_TRUE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value));
2097 EXPECT_EQ(-12.0, value);
2098 }
2099
2100 UnloadPage(page);
2101}
Ryan Smith23fdf892019-07-17 21:51:26 +00002102
2103TEST_F(FPDFAnnotEmbedderTest, IsCheckedCheckbox) {
2104 // Open a file with checkbox and radiobuttons widget annotations and load its
2105 // first page.
2106 ASSERT_TRUE(OpenDocument("click_form.pdf"));
2107 FPDF_PAGE page = LoadPage(0);
2108 ASSERT_TRUE(page);
2109
2110 {
2111 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 1));
2112 ASSERT_TRUE(annot);
2113 ASSERT_FALSE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2114 }
2115
2116 UnloadPage(page);
2117}
2118
2119TEST_F(FPDFAnnotEmbedderTest, IsCheckedCheckboxReadOnly) {
2120 // Open a file with checkbox and radiobutton widget annotations and load its
2121 // first page.
2122 ASSERT_TRUE(OpenDocument("click_form.pdf"));
2123 FPDF_PAGE page = LoadPage(0);
2124 ASSERT_TRUE(page);
2125
2126 {
2127 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2128 ASSERT_TRUE(annot);
2129 ASSERT_TRUE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2130 }
2131
2132 UnloadPage(page);
2133}
2134
2135TEST_F(FPDFAnnotEmbedderTest, IsCheckedRadioButton) {
2136 // Open a file with checkbox and radiobutton widget annotations and load its
2137 // first page.
2138 ASSERT_TRUE(OpenDocument("click_form.pdf"));
2139 FPDF_PAGE page = LoadPage(0);
2140 ASSERT_TRUE(page);
2141
2142 {
2143 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 5));
2144 ASSERT_TRUE(annot);
2145 ASSERT_FALSE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2146
2147 annot.reset(FPDFPage_GetAnnot(page, 6));
2148 ASSERT_FALSE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2149
2150 annot.reset(FPDFPage_GetAnnot(page, 7));
2151 ASSERT_TRUE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2152 }
2153
2154 UnloadPage(page);
2155}
2156
2157TEST_F(FPDFAnnotEmbedderTest, IsCheckedRadioButtonReadOnly) {
2158 // Open a file with checkbox and radiobutton widget annotations and load its
2159 // first page.
2160 ASSERT_TRUE(OpenDocument("click_form.pdf"));
2161 FPDF_PAGE page = LoadPage(0);
2162 ASSERT_TRUE(page);
2163
2164 {
2165 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
2166 ASSERT_TRUE(annot);
2167 ASSERT_FALSE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2168
2169 annot.reset(FPDFPage_GetAnnot(page, 3));
2170 ASSERT_FALSE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2171
2172 annot.reset(FPDFPage_GetAnnot(page, 4));
2173 ASSERT_TRUE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2174 }
2175
2176 UnloadPage(page);
2177}
2178
2179TEST_F(FPDFAnnotEmbedderTest, IsCheckedInvalidArguments) {
2180 // Open a file with checkbox and radiobuttons widget annotations and load its
2181 // first page.
2182 ASSERT_TRUE(OpenDocument("click_form.pdf"));
2183 FPDF_PAGE page = LoadPage(0);
2184 ASSERT_TRUE(page);
2185
2186 {
2187 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2188 ASSERT_TRUE(annot);
2189 ASSERT_FALSE(FPDFAnnot_IsChecked(nullptr, annot.get()));
2190 ASSERT_FALSE(FPDFAnnot_IsChecked(form_handle(), nullptr));
2191 ASSERT_FALSE(FPDFAnnot_IsChecked(nullptr, nullptr));
2192 }
2193
2194 UnloadPage(page);
2195}
2196
2197TEST_F(FPDFAnnotEmbedderTest, IsCheckedInvalidWidgetType) {
2198 // Open a file with text widget annotations and load its first page.
2199 ASSERT_TRUE(OpenDocument("text_form.pdf"));
2200 FPDF_PAGE page = LoadPage(0);
2201 ASSERT_TRUE(page);
2202
2203 {
2204 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2205 ASSERT_TRUE(annot);
2206 ASSERT_FALSE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2207 }
2208
2209 UnloadPage(page);
2210}