blob: 1e0ebd8c018bd8e64613e62664fff52d005a5d79 [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"
Mansi Awasthi07bf7e62020-01-24 10:34:17 +000017#include "public/fpdf_formfill.h"
Jane Liu4fd9a472017-06-01 18:56:09 -040018#include "public/fpdfview.h"
19#include "testing/embedder_test.h"
Lei Zhangb6992dd2019-02-05 23:30:20 +000020#include "testing/fx_string_testhelpers.h"
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +000021#include "testing/gmock/include/gmock/gmock-matchers.h"
Jane Liu4fd9a472017-06-01 18:56:09 -040022#include "testing/gtest/include/gtest/gtest.h"
Lei Zhang5bf8c7f2019-04-08 17:50:11 +000023#include "testing/utils/hash.h"
Jane Liu4fd9a472017-06-01 18:56:09 -040024
Lei Zhangab41f252018-12-23 03:10:50 +000025class FPDFAnnotEmbedderTest : public EmbedderTest {};
Jane Liu4fd9a472017-06-01 18:56:09 -040026
Lei Zhangab41f252018-12-23 03:10:50 +000027TEST_F(FPDFAnnotEmbedderTest, BadParams) {
Lei Zhang7557e7b2018-09-14 17:02:40 +000028 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
29 FPDF_PAGE page = LoadPage(0);
30 ASSERT_TRUE(page);
31
32 EXPECT_EQ(0, FPDFPage_GetAnnotCount(nullptr));
33
34 EXPECT_FALSE(FPDFPage_GetAnnot(nullptr, 0));
35 EXPECT_FALSE(FPDFPage_GetAnnot(nullptr, -1));
36 EXPECT_FALSE(FPDFPage_GetAnnot(nullptr, 1));
37 EXPECT_FALSE(FPDFPage_GetAnnot(page, -1));
38 EXPECT_FALSE(FPDFPage_GetAnnot(page, 1));
39
40 EXPECT_EQ(FPDF_ANNOT_UNKNOWN, FPDFAnnot_GetSubtype(nullptr));
41
42 EXPECT_EQ(0, FPDFAnnot_GetObjectCount(nullptr));
43
44 EXPECT_FALSE(FPDFAnnot_GetObject(nullptr, 0));
45 EXPECT_FALSE(FPDFAnnot_GetObject(nullptr, -1));
46 EXPECT_FALSE(FPDFAnnot_GetObject(nullptr, 1));
47
48 EXPECT_FALSE(FPDFAnnot_HasKey(nullptr, "foo"));
49
Lei Zhang4f556b82019-04-08 16:32:41 +000050 static const wchar_t kContents[] = L"Bar";
Lei Zhangf0f67682019-04-08 17:03:21 +000051 ScopedFPDFWideString text = GetFPDFWideString(kContents);
Lei Zhang7557e7b2018-09-14 17:02:40 +000052 EXPECT_FALSE(FPDFAnnot_SetStringValue(nullptr, "foo", text.get()));
53
Lei Zhang5bf8c7f2019-04-08 17:50:11 +000054 FPDF_WCHAR buffer[64];
Lei Zhang7557e7b2018-09-14 17:02:40 +000055 EXPECT_EQ(0u, FPDFAnnot_GetStringValue(nullptr, "foo", nullptr, 0));
56 EXPECT_EQ(0u, FPDFAnnot_GetStringValue(nullptr, "foo", buffer, 0));
57 EXPECT_EQ(0u,
58 FPDFAnnot_GetStringValue(nullptr, "foo", buffer, sizeof(buffer)));
59
60 UnloadPage(page);
61}
62
Lei Zhang3d9a0972019-03-04 19:34:09 +000063TEST_F(FPDFAnnotEmbedderTest, BadAnnotsEntry) {
64 ASSERT_TRUE(OpenDocument("bad_annots_entry.pdf"));
65 FPDF_PAGE page = LoadPage(0);
66 ASSERT_TRUE(page);
67
68 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
Lei Zhang98dc8c02019-03-04 19:40:30 +000069 EXPECT_FALSE(FPDFPage_GetAnnot(page, 0));
Lei Zhang3d9a0972019-03-04 19:34:09 +000070
71 UnloadPage(page);
72}
73
Lei Zhangab41f252018-12-23 03:10:50 +000074TEST_F(FPDFAnnotEmbedderTest, RenderAnnotWithOnlyRolloverAP) {
Jane Liue17011d2017-06-21 12:18:37 -040075 // Open a file with one annotation and load its first page.
76 ASSERT_TRUE(OpenDocument("annotation_highlight_rollover_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +000077 FPDF_PAGE page = LoadPage(0);
Jane Liue17011d2017-06-21 12:18:37 -040078 ASSERT_TRUE(page);
79
80 // This annotation has a malformed appearance stream, which does not have its
81 // normal appearance defined, only its rollover appearance. In this case, its
82 // normal appearance should be generated, allowing the highlight annotation to
83 // still display.
Tom Sepeze08d2b12018-04-25 18:49:32 +000084 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhanga98e3662018-02-07 20:28:35 +000085 CompareBitmap(bitmap.get(), 612, 792, "dc98f06da047bd8aabfa99562d2cbd1e");
Jane Liue17011d2017-06-21 12:18:37 -040086
87 UnloadPage(page);
88}
89
Lei Zhang03e5e682019-09-16 19:45:55 +000090// TODO(crbug.com/pdfium/11): Fix this test and enable.
91#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
92#define MAYBE_RenderMultilineMarkupAnnotWithoutAP \
93 DISABLED_RenderMultilineMarkupAnnotWithoutAP
94#else
95#define MAYBE_RenderMultilineMarkupAnnotWithoutAP \
96 RenderMultilineMarkupAnnotWithoutAP
97#endif
98TEST_F(FPDFAnnotEmbedderTest, MAYBE_RenderMultilineMarkupAnnotWithoutAP) {
Lei Zhang4f556b82019-04-08 16:32:41 +000099 static const char kMd5[] = "76512832d88017668d9acc7aacd13dae";
Henrique Nakashima5098b252018-03-26 21:46:00 +0000100 // Open a file with multiline markup annotations.
Ralf Sipplb3a52402018-03-19 23:30:28 +0000101 ASSERT_TRUE(OpenDocument("annotation_markup_multiline_no_ap.pdf"));
102 FPDF_PAGE page = LoadPage(0);
103 ASSERT_TRUE(page);
104
Tom Sepeze08d2b12018-04-25 18:49:32 +0000105 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000106 CompareBitmap(bitmap.get(), 595, 842, kMd5);
Ralf Sipplb3a52402018-03-19 23:30:28 +0000107
108 UnloadPage(page);
109}
110
Lei Zhangab41f252018-12-23 03:10:50 +0000111TEST_F(FPDFAnnotEmbedderTest, ExtractHighlightLongContent) {
Jane Liu4fd9a472017-06-01 18:56:09 -0400112 // Open a file with one annotation and load its first page.
113 ASSERT_TRUE(OpenDocument("annotation_highlight_long_content.pdf"));
Tom Sepez507d0192018-11-07 16:37:51 +0000114 FPDF_PAGE page = LoadPageNoEvents(0);
Jane Liu4fd9a472017-06-01 18:56:09 -0400115 ASSERT_TRUE(page);
116
117 // Check that there is a total of 1 annotation on its first page.
118 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
119
120 // Check that the annotation is of type "highlight".
Lei Zhanga21d5932018-02-05 18:28:38 +0000121 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000122 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000123 ASSERT_TRUE(annot);
124 EXPECT_EQ(FPDF_ANNOT_HIGHLIGHT, FPDFAnnot_GetSubtype(annot.get()));
Jane Liu4fd9a472017-06-01 18:56:09 -0400125
Lei Zhanga21d5932018-02-05 18:28:38 +0000126 // Check that the annotation color is yellow.
127 unsigned int R;
128 unsigned int G;
129 unsigned int B;
130 unsigned int A;
Lei Zhang75c81712018-02-08 17:22:39 +0000131 ASSERT_TRUE(FPDFAnnot_GetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, &R,
Lei Zhanga21d5932018-02-05 18:28:38 +0000132 &G, &B, &A));
133 EXPECT_EQ(255u, R);
134 EXPECT_EQ(255u, G);
135 EXPECT_EQ(0u, B);
136 EXPECT_EQ(255u, A);
Jane Liu4fd9a472017-06-01 18:56:09 -0400137
Lei Zhanga21d5932018-02-05 18:28:38 +0000138 // Check that the author is correct.
Lei Zhang4f556b82019-04-08 16:32:41 +0000139 static const char kAuthorKey[] = "T";
Lei Zhanga21d5932018-02-05 18:28:38 +0000140 EXPECT_EQ(FPDF_OBJECT_STRING,
141 FPDFAnnot_GetValueType(annot.get(), kAuthorKey));
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000142 unsigned long length_bytes =
Lei Zhanga21d5932018-02-05 18:28:38 +0000143 FPDFAnnot_GetStringValue(annot.get(), kAuthorKey, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000144 ASSERT_EQ(28u, length_bytes);
145 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
Lei Zhanga21d5932018-02-05 18:28:38 +0000146 EXPECT_EQ(28u, FPDFAnnot_GetStringValue(annot.get(), kAuthorKey, buf.data(),
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000147 length_bytes));
148 EXPECT_EQ(L"Jae Hyun Park", GetPlatformWString(buf.data()));
Jane Liu4fd9a472017-06-01 18:56:09 -0400149
Lei Zhanga21d5932018-02-05 18:28:38 +0000150 // Check that the content is correct.
Lei Zhanga5c1daf2019-01-31 21:56:47 +0000151 EXPECT_EQ(
152 FPDF_OBJECT_STRING,
153 FPDFAnnot_GetValueType(annot.get(), pdfium::annotation::kContents));
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000154 length_bytes = FPDFAnnot_GetStringValue(
155 annot.get(), pdfium::annotation::kContents, nullptr, 0);
156 ASSERT_EQ(2690u, length_bytes);
157 buf = GetFPDFWideStringBuffer(length_bytes);
158 EXPECT_EQ(2690u, FPDFAnnot_GetStringValue(annot.get(),
159 pdfium::annotation::kContents,
160 buf.data(), length_bytes));
Lei Zhang4f556b82019-04-08 16:32:41 +0000161 static const wchar_t kContents[] =
Lei Zhanga21d5932018-02-05 18:28:38 +0000162 L"This is a note for that highlight annotation. Very long highlight "
163 "annotation. Long long long Long 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 longLong long longLong long longLong long longLong long "
181 "longLong long long. END";
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000182 EXPECT_EQ(kContents, GetPlatformWString(buf.data()));
Jane Liu4fd9a472017-06-01 18:56:09 -0400183
Lei Zhanga21d5932018-02-05 18:28:38 +0000184 // Check that the quadpoints are correct.
185 FS_QUADPOINTSF quadpoints;
Ralf Sippl16381792018-04-12 21:20:26 +0000186 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot.get(), 0, &quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000187 EXPECT_EQ(115.802643f, quadpoints.x1);
188 EXPECT_EQ(718.913940f, quadpoints.y1);
189 EXPECT_EQ(157.211182f, quadpoints.x4);
190 EXPECT_EQ(706.264465f, quadpoints.y4);
191 }
Tom Sepez507d0192018-11-07 16:37:51 +0000192 UnloadPageNoEvents(page);
Jane Liu4fd9a472017-06-01 18:56:09 -0400193}
194
Lei Zhang03e5e682019-09-16 19:45:55 +0000195// TODO(crbug.com/pdfium/11): Fix this test and enable.
196#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
197#define MAYBE_ExtractInkMultiple DISABLED_ExtractInkMultiple
198#else
199#define MAYBE_ExtractInkMultiple ExtractInkMultiple
200#endif
201TEST_F(FPDFAnnotEmbedderTest, MAYBE_ExtractInkMultiple) {
Jane Liu4fd9a472017-06-01 18:56:09 -0400202 // Open a file with three annotations and load its first page.
203 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
Tom Sepez507d0192018-11-07 16:37:51 +0000204 FPDF_PAGE page = LoadPageNoEvents(0);
Jane Liu4fd9a472017-06-01 18:56:09 -0400205 ASSERT_TRUE(page);
206
207 // Check that there is a total of 3 annotation on its first page.
208 EXPECT_EQ(3, FPDFPage_GetAnnotCount(page));
209
Lei Zhanga21d5932018-02-05 18:28:38 +0000210 {
211 // Check that the third annotation is of type "ink".
Tom Sepeze08d2b12018-04-25 18:49:32 +0000212 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +0000213 ASSERT_TRUE(annot);
214 EXPECT_EQ(FPDF_ANNOT_INK, FPDFAnnot_GetSubtype(annot.get()));
Jane Liu4fd9a472017-06-01 18:56:09 -0400215
Lei Zhanga21d5932018-02-05 18:28:38 +0000216 // Check that the annotation color is blue with opacity.
217 unsigned int R;
218 unsigned int G;
219 unsigned int B;
220 unsigned int A;
Lei Zhang75c81712018-02-08 17:22:39 +0000221 ASSERT_TRUE(FPDFAnnot_GetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, &R,
Lei Zhanga21d5932018-02-05 18:28:38 +0000222 &G, &B, &A));
223 EXPECT_EQ(0u, R);
224 EXPECT_EQ(0u, G);
225 EXPECT_EQ(255u, B);
226 EXPECT_EQ(76u, A);
Jane Liu4fd9a472017-06-01 18:56:09 -0400227
Lei Zhanga21d5932018-02-05 18:28:38 +0000228 // Check that there is no content.
Lei Zhanga5c1daf2019-01-31 21:56:47 +0000229 EXPECT_EQ(2u, FPDFAnnot_GetStringValue(
230 annot.get(), pdfium::annotation::kContents, nullptr, 0));
Jane Liu4fd9a472017-06-01 18:56:09 -0400231
Lei Zhang4f556b82019-04-08 16:32:41 +0000232 // Check that the rectangle coordinates are correct.
Lei Zhanga21d5932018-02-05 18:28:38 +0000233 // Note that upon rendering, the rectangle coordinates will be adjusted.
234 FS_RECTF rect;
235 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
236 EXPECT_EQ(351.820404f, rect.left);
237 EXPECT_EQ(583.830688f, rect.bottom);
238 EXPECT_EQ(475.336090f, rect.right);
239 EXPECT_EQ(681.535034f, rect.top);
240 }
Tom Sepezef43c262018-11-07 16:41:32 +0000241 {
242 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
243 CompareBitmap(bitmap.get(), 612, 792, "354002e1c4386d38fdde29ef8d61074a");
244 }
Tom Sepez507d0192018-11-07 16:37:51 +0000245 UnloadPageNoEvents(page);
Jane Liu4fd9a472017-06-01 18:56:09 -0400246}
Jane Liu20eafda2017-06-07 10:33:24 -0400247
Lei Zhangab41f252018-12-23 03:10:50 +0000248TEST_F(FPDFAnnotEmbedderTest, AddIllegalSubtypeAnnotation) {
Jane Liu20eafda2017-06-07 10:33:24 -0400249 // Open a file with one annotation and load its first page.
250 ASSERT_TRUE(OpenDocument("annotation_highlight_long_content.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000251 FPDF_PAGE page = LoadPage(0);
Jane Liu20eafda2017-06-07 10:33:24 -0400252 ASSERT_TRUE(page);
253
254 // Add an annotation with an illegal subtype.
Jane Liud60e9ad2017-06-26 11:28:36 -0400255 ASSERT_FALSE(FPDFPage_CreateAnnot(page, -1));
Jane Liu20eafda2017-06-07 10:33:24 -0400256
257 UnloadPage(page);
258}
259
Lei Zhangab41f252018-12-23 03:10:50 +0000260TEST_F(FPDFAnnotEmbedderTest, AddFirstTextAnnotation) {
Jane Liu20eafda2017-06-07 10:33:24 -0400261 // Open a file with no annotation and load its first page.
262 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000263 FPDF_PAGE page = LoadPage(0);
Jane Liu20eafda2017-06-07 10:33:24 -0400264 ASSERT_TRUE(page);
265 EXPECT_EQ(0, FPDFPage_GetAnnotCount(page));
266
Lei Zhanga21d5932018-02-05 18:28:38 +0000267 {
268 // Add a text annotation to the page.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000269 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_TEXT));
Lei Zhanga21d5932018-02-05 18:28:38 +0000270 ASSERT_TRUE(annot);
Jane Liu20eafda2017-06-07 10:33:24 -0400271
Lei Zhanga21d5932018-02-05 18:28:38 +0000272 // Check that there is now 1 annotations on this page.
273 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
Jane Liu20eafda2017-06-07 10:33:24 -0400274
Lei Zhanga21d5932018-02-05 18:28:38 +0000275 // Check that the subtype of the annotation is correct.
276 EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
277 }
Jane Liue10509a2017-06-20 16:47:41 -0400278
Lei Zhanga21d5932018-02-05 18:28:38 +0000279 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000280 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000281 ASSERT_TRUE(annot);
282 EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
Jane Liu20eafda2017-06-07 10:33:24 -0400283
Lei Zhanga21d5932018-02-05 18:28:38 +0000284 // Set the color of the annotation.
285 ASSERT_TRUE(FPDFAnnot_SetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, 51,
286 102, 153, 204));
287 // Check that the color has been set correctly.
288 unsigned int R;
289 unsigned int G;
290 unsigned int B;
291 unsigned int A;
Lei Zhang75c81712018-02-08 17:22:39 +0000292 ASSERT_TRUE(FPDFAnnot_GetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, &R,
Lei Zhanga21d5932018-02-05 18:28:38 +0000293 &G, &B, &A));
294 EXPECT_EQ(51u, R);
295 EXPECT_EQ(102u, G);
296 EXPECT_EQ(153u, B);
297 EXPECT_EQ(204u, A);
Jane Liu20eafda2017-06-07 10:33:24 -0400298
Lei Zhanga21d5932018-02-05 18:28:38 +0000299 // Change the color of the annotation.
300 ASSERT_TRUE(FPDFAnnot_SetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, 204,
301 153, 102, 51));
302 // Check that the color has been set correctly.
Lei Zhang75c81712018-02-08 17:22:39 +0000303 ASSERT_TRUE(FPDFAnnot_GetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, &R,
Lei Zhanga21d5932018-02-05 18:28:38 +0000304 &G, &B, &A));
305 EXPECT_EQ(204u, R);
306 EXPECT_EQ(153u, G);
307 EXPECT_EQ(102u, B);
308 EXPECT_EQ(51u, A);
Jane Liu20eafda2017-06-07 10:33:24 -0400309
Lei Zhanga21d5932018-02-05 18:28:38 +0000310 // Set the annotation rectangle.
311 FS_RECTF rect;
312 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
313 EXPECT_EQ(0.f, rect.left);
314 EXPECT_EQ(0.f, rect.right);
315 rect.left = 35;
316 rect.bottom = 150;
317 rect.right = 53;
318 rect.top = 165;
319 ASSERT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
320 // Check that the annotation rectangle has been set correctly.
321 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
322 EXPECT_EQ(35.f, rect.left);
323 EXPECT_EQ(150.f, rect.bottom);
324 EXPECT_EQ(53.f, rect.right);
325 EXPECT_EQ(165.f, rect.top);
Jane Liu20eafda2017-06-07 10:33:24 -0400326
Lei Zhanga21d5932018-02-05 18:28:38 +0000327 // Set the content of the annotation.
Lei Zhang4f556b82019-04-08 16:32:41 +0000328 static const wchar_t kContents[] = L"Hello! This is a customized content.";
Lei Zhangf0f67682019-04-08 17:03:21 +0000329 ScopedFPDFWideString text = GetFPDFWideString(kContents);
Lei Zhanga5c1daf2019-01-31 21:56:47 +0000330 ASSERT_TRUE(FPDFAnnot_SetStringValue(
331 annot.get(), pdfium::annotation::kContents, text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +0000332 // Check that the content has been set correctly.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000333 unsigned long length_bytes = FPDFAnnot_GetStringValue(
Lei Zhanga5c1daf2019-01-31 21:56:47 +0000334 annot.get(), pdfium::annotation::kContents, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000335 ASSERT_EQ(74u, length_bytes);
336 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
337 EXPECT_EQ(74u, FPDFAnnot_GetStringValue(annot.get(),
338 pdfium::annotation::kContents,
339 buf.data(), length_bytes));
340 EXPECT_EQ(kContents, GetPlatformWString(buf.data()));
Lei Zhanga21d5932018-02-05 18:28:38 +0000341 }
Jane Liu20eafda2017-06-07 10:33:24 -0400342 UnloadPage(page);
343}
344
Lei Zhang03e5e682019-09-16 19:45:55 +0000345// TODO(crbug.com/pdfium/11): Fix this test and enable.
346#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
347#define MAYBE_AddAndSaveUnderlineAnnotation \
348 DISABLED_AddAndSaveUnderlineAnnotation
349#else
350#define MAYBE_AddAndSaveUnderlineAnnotation AddAndSaveUnderlineAnnotation
351#endif
352TEST_F(FPDFAnnotEmbedderTest, MAYBE_AddAndSaveUnderlineAnnotation) {
Jane Liu20eafda2017-06-07 10:33:24 -0400353 // Open a file with one annotation and load its first page.
354 ASSERT_TRUE(OpenDocument("annotation_highlight_long_content.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000355 FPDF_PAGE page = LoadPage(0);
Jane Liu20eafda2017-06-07 10:33:24 -0400356 ASSERT_TRUE(page);
357
358 // Check that there is a total of one annotation on its first page, and verify
359 // its quadpoints.
360 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
Jane Liu0c6b07d2017-08-15 10:50:22 -0400361 FS_QUADPOINTSF quadpoints;
Lei Zhanga21d5932018-02-05 18:28:38 +0000362 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000363 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000364 ASSERT_TRUE(annot);
Ralf Sippl16381792018-04-12 21:20:26 +0000365 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot.get(), 0, &quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000366 EXPECT_EQ(115.802643f, quadpoints.x1);
367 EXPECT_EQ(718.913940f, quadpoints.y1);
368 EXPECT_EQ(157.211182f, quadpoints.x4);
369 EXPECT_EQ(706.264465f, quadpoints.y4);
370 }
Jane Liu20eafda2017-06-07 10:33:24 -0400371
372 // Add an underline annotation to the page and set its quadpoints.
Lei Zhanga21d5932018-02-05 18:28:38 +0000373 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000374 ScopedFPDFAnnotation annot(
Lei Zhanga21d5932018-02-05 18:28:38 +0000375 FPDFPage_CreateAnnot(page, FPDF_ANNOT_UNDERLINE));
376 ASSERT_TRUE(annot);
377 quadpoints.x1 = 140.802643f;
378 quadpoints.x3 = 140.802643f;
Ralf Sippl16381792018-04-12 21:20:26 +0000379 ASSERT_TRUE(FPDFAnnot_AppendAttachmentPoints(annot.get(), &quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000380 }
Jane Liu20eafda2017-06-07 10:33:24 -0400381
382 // Save the document, closing the page and document.
383 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang75c81712018-02-08 17:22:39 +0000384 UnloadPage(page);
Jane Liu20eafda2017-06-07 10:33:24 -0400385
386 // Open the saved document.
Lei Zhang4f556b82019-04-08 16:32:41 +0000387 static const char kMd5[] = "dba153419f67b7c0c0e3d22d3e8910d5";
Dan Sinclair04e4dc82017-10-18 12:17:14 -0400388
Lei Zhang0b494052019-01-31 21:41:15 +0000389 ASSERT_TRUE(OpenSavedDocument());
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000390 page = LoadSavedPage(0);
Lei Zhang4f556b82019-04-08 16:32:41 +0000391 VerifySavedRendering(page, 612, 792, kMd5);
Jane Liu20eafda2017-06-07 10:33:24 -0400392
393 // Check that the saved document has 2 annotations on the first page
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000394 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
Jane Liu20eafda2017-06-07 10:33:24 -0400395
Lei Zhanga21d5932018-02-05 18:28:38 +0000396 {
397 // Check that the second annotation is an underline annotation and verify
398 // its quadpoints.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000399 ScopedFPDFAnnotation new_annot(FPDFPage_GetAnnot(page, 1));
Lei Zhanga21d5932018-02-05 18:28:38 +0000400 ASSERT_TRUE(new_annot);
401 EXPECT_EQ(FPDF_ANNOT_UNDERLINE, FPDFAnnot_GetSubtype(new_annot.get()));
402 FS_QUADPOINTSF new_quadpoints;
403 ASSERT_TRUE(
Ralf Sippl16381792018-04-12 21:20:26 +0000404 FPDFAnnot_GetAttachmentPoints(new_annot.get(), 0, &new_quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000405 EXPECT_NEAR(quadpoints.x1, new_quadpoints.x1, 0.001f);
406 EXPECT_NEAR(quadpoints.y1, new_quadpoints.y1, 0.001f);
407 EXPECT_NEAR(quadpoints.x4, new_quadpoints.x4, 0.001f);
408 EXPECT_NEAR(quadpoints.y4, new_quadpoints.y4, 0.001f);
409 }
Dan Sinclair04e4dc82017-10-18 12:17:14 -0400410
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000411 CloseSavedPage(page);
Dan Sinclair04e4dc82017-10-18 12:17:14 -0400412 CloseSavedDocument();
Jane Liu20eafda2017-06-07 10:33:24 -0400413}
Jane Liu06462752017-06-27 16:41:14 -0400414
Lei Zhangab41f252018-12-23 03:10:50 +0000415TEST_F(FPDFAnnotEmbedderTest, GetAndSetQuadPoints) {
Ralf Sippl16381792018-04-12 21:20:26 +0000416 // Open a file with four annotations and load its first page.
417 ASSERT_TRUE(OpenDocument("annotation_highlight_square_with_ap.pdf"));
418 FPDF_PAGE page = LoadPage(0);
419 ASSERT_TRUE(page);
420 EXPECT_EQ(4, FPDFPage_GetAnnotCount(page));
421
422 // Retrieve the highlight annotation.
423 FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 0);
424 ASSERT_TRUE(annot);
425 ASSERT_EQ(FPDF_ANNOT_HIGHLIGHT, FPDFAnnot_GetSubtype(annot));
426
427 FS_QUADPOINTSF quadpoints;
428 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot, 0, &quadpoints));
429
430 {
431 // Verify the current one set of quadpoints.
432 ASSERT_EQ(1u, FPDFAnnot_CountAttachmentPoints(annot));
433
434 EXPECT_NEAR(72.0000f, quadpoints.x1, 0.001f);
435 EXPECT_NEAR(720.792f, quadpoints.y1, 0.001f);
436 EXPECT_NEAR(132.055f, quadpoints.x4, 0.001f);
437 EXPECT_NEAR(704.796f, quadpoints.y4, 0.001f);
438 }
439
440 {
441 // Update the quadpoints.
442 FS_QUADPOINTSF new_quadpoints = quadpoints;
443 new_quadpoints.y1 -= 20.f;
444 new_quadpoints.y2 -= 20.f;
445 new_quadpoints.y3 -= 20.f;
446 new_quadpoints.y4 -= 20.f;
447 ASSERT_TRUE(FPDFAnnot_SetAttachmentPoints(annot, 0, &new_quadpoints));
448
449 // Verify added quadpoint set
450 ASSERT_EQ(1u, FPDFAnnot_CountAttachmentPoints(annot));
451 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot, 0, &quadpoints));
452 EXPECT_NEAR(new_quadpoints.x1, quadpoints.x1, 0.001f);
453 EXPECT_NEAR(new_quadpoints.y1, quadpoints.y1, 0.001f);
454 EXPECT_NEAR(new_quadpoints.x4, quadpoints.x4, 0.001f);
455 EXPECT_NEAR(new_quadpoints.y4, quadpoints.y4, 0.001f);
456 }
457
458 {
459 // Append a new set of quadpoints.
460 FS_QUADPOINTSF new_quadpoints = quadpoints;
461 new_quadpoints.y1 += 20.f;
462 new_quadpoints.y2 += 20.f;
463 new_quadpoints.y3 += 20.f;
464 new_quadpoints.y4 += 20.f;
465 ASSERT_TRUE(FPDFAnnot_AppendAttachmentPoints(annot, &new_quadpoints));
466
467 // Verify added quadpoint set
468 ASSERT_EQ(2u, FPDFAnnot_CountAttachmentPoints(annot));
469 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot, 1, &quadpoints));
470 EXPECT_NEAR(new_quadpoints.x1, quadpoints.x1, 0.001f);
471 EXPECT_NEAR(new_quadpoints.y1, quadpoints.y1, 0.001f);
472 EXPECT_NEAR(new_quadpoints.x4, quadpoints.x4, 0.001f);
473 EXPECT_NEAR(new_quadpoints.y4, quadpoints.y4, 0.001f);
474 }
475
476 {
477 // Setting and getting quadpoints at out-of-bound index should fail
478 EXPECT_FALSE(FPDFAnnot_SetAttachmentPoints(annot, 300000, &quadpoints));
479 EXPECT_FALSE(FPDFAnnot_GetAttachmentPoints(annot, 300000, &quadpoints));
480 }
481
482 FPDFPage_CloseAnnot(annot);
483
484 // Retrieve the square annotation
485 FPDF_ANNOTATION squareAnnot = FPDFPage_GetAnnot(page, 2);
486
487 {
488 // Check that attempting to set its quadpoints would fail
489 ASSERT_TRUE(squareAnnot);
490 EXPECT_EQ(FPDF_ANNOT_SQUARE, FPDFAnnot_GetSubtype(squareAnnot));
491 EXPECT_EQ(0u, FPDFAnnot_CountAttachmentPoints(squareAnnot));
492 EXPECT_FALSE(FPDFAnnot_SetAttachmentPoints(squareAnnot, 0, &quadpoints));
493 }
494
495 FPDFPage_CloseAnnot(squareAnnot);
Ralf Sippl16381792018-04-12 21:20:26 +0000496 UnloadPage(page);
497}
498
Lei Zhang03e5e682019-09-16 19:45:55 +0000499// TODO(crbug.com/pdfium/11): Fix this test and enable.
500#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
501#define MAYBE_ModifyRectQuadpointsWithAP DISABLED_ModifyRectQuadpointsWithAP
502#else
503#define MAYBE_ModifyRectQuadpointsWithAP ModifyRectQuadpointsWithAP
504#endif
505TEST_F(FPDFAnnotEmbedderTest, MAYBE_ModifyRectQuadpointsWithAP) {
Lei Zhange4cdac52019-04-30 16:45:57 +0000506#if defined(OS_MACOSX)
Lei Zhang4f556b82019-04-08 16:32:41 +0000507 static const char kMd5Original[] = "63af8432fab95a67cdebb7cd0e514941";
508 static const char kMd5ModifiedHighlight[] =
509 "aec26075011349dec9bace891856b5f2";
510 static const char kMd5ModifiedSquare[] = "057f57a32be95975775e5ec513fdcb56";
Lei Zhange67bcc72019-04-30 18:55:58 +0000511#elif defined(OS_WIN)
Lei Zhang4f556b82019-04-08 16:32:41 +0000512 static const char kMd5Original[] = "0e27376094f11490f74c65f3dc3a42c5";
513 static const char kMd5ModifiedHighlight[] =
514 "66f3caef3a7d488a4fa1ad37fc06310e";
515 static const char kMd5ModifiedSquare[] = "a456dad0bc6801ee2d6408a4394af563";
Jane Liub370e5a2017-08-16 13:24:58 -0400516#else
Lei Zhang4f556b82019-04-08 16:32:41 +0000517 static const char kMd5Original[] = "0e27376094f11490f74c65f3dc3a42c5";
518 static const char kMd5ModifiedHighlight[] =
519 "66f3caef3a7d488a4fa1ad37fc06310e";
520 static const char kMd5ModifiedSquare[] = "a456dad0bc6801ee2d6408a4394af563";
Jane Liub370e5a2017-08-16 13:24:58 -0400521#endif
522
Jane Liu06462752017-06-27 16:41:14 -0400523 // Open a file with four annotations and load its first page.
524 ASSERT_TRUE(OpenDocument("annotation_highlight_square_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000525 FPDF_PAGE page = LoadPage(0);
Jane Liu06462752017-06-27 16:41:14 -0400526 ASSERT_TRUE(page);
527 EXPECT_EQ(4, FPDFPage_GetAnnotCount(page));
528
Jane Liub370e5a2017-08-16 13:24:58 -0400529 // Check that the original file renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000530 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000531 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000532 CompareBitmap(bitmap.get(), 612, 792, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000533 }
Jane Liub370e5a2017-08-16 13:24:58 -0400534
Jane Liu0c6b07d2017-08-15 10:50:22 -0400535 FS_RECTF rect;
Jane Liu0c6b07d2017-08-15 10:50:22 -0400536 FS_RECTF new_rect;
Lei Zhanga21d5932018-02-05 18:28:38 +0000537
538 // Retrieve the highlight annotation which has its AP stream already defined.
539 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000540 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000541 ASSERT_TRUE(annot);
542 EXPECT_EQ(FPDF_ANNOT_HIGHLIGHT, FPDFAnnot_GetSubtype(annot.get()));
543
544 // Check that color cannot be set when an AP stream is defined already.
545 EXPECT_FALSE(FPDFAnnot_SetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, 51,
546 102, 153, 204));
547
548 // Verify its attachment points.
549 FS_QUADPOINTSF quadpoints;
Ralf Sippl16381792018-04-12 21:20:26 +0000550 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot.get(), 0, &quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000551 EXPECT_NEAR(72.0000f, quadpoints.x1, 0.001f);
552 EXPECT_NEAR(720.792f, quadpoints.y1, 0.001f);
553 EXPECT_NEAR(132.055f, quadpoints.x4, 0.001f);
554 EXPECT_NEAR(704.796f, quadpoints.y4, 0.001f);
555
556 // Check that updating the attachment points would succeed.
557 quadpoints.x1 -= 50.f;
558 quadpoints.x2 -= 50.f;
559 quadpoints.x3 -= 50.f;
560 quadpoints.x4 -= 50.f;
Ralf Sippl16381792018-04-12 21:20:26 +0000561 ASSERT_TRUE(FPDFAnnot_SetAttachmentPoints(annot.get(), 0, &quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000562 FS_QUADPOINTSF new_quadpoints;
Ralf Sippl16381792018-04-12 21:20:26 +0000563 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot.get(), 0, &new_quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000564 EXPECT_EQ(quadpoints.x1, new_quadpoints.x1);
565 EXPECT_EQ(quadpoints.y1, new_quadpoints.y1);
566 EXPECT_EQ(quadpoints.x4, new_quadpoints.x4);
567 EXPECT_EQ(quadpoints.y4, new_quadpoints.y4);
568
569 // Check that updating quadpoints does not change the annotation's position.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000570 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000571 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000572 CompareBitmap(bitmap.get(), 612, 792, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000573 }
Lei Zhanga21d5932018-02-05 18:28:38 +0000574
575 // Verify its annotation rectangle.
576 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
577 EXPECT_NEAR(67.7299f, rect.left, 0.001f);
578 EXPECT_NEAR(704.296f, rect.bottom, 0.001f);
579 EXPECT_NEAR(136.325f, rect.right, 0.001f);
580 EXPECT_NEAR(721.292f, rect.top, 0.001f);
581
582 // Check that updating the rectangle would succeed.
583 rect.left -= 60.f;
584 rect.right -= 60.f;
585 ASSERT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
586 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &new_rect));
587 EXPECT_EQ(rect.right, new_rect.right);
588 }
Jane Liu06462752017-06-27 16:41:14 -0400589
Jane Liub370e5a2017-08-16 13:24:58 -0400590 // Check that updating the rectangle changes the annotation's position.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000591 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000592 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000593 CompareBitmap(bitmap.get(), 612, 792, kMd5ModifiedHighlight);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000594 }
Jane Liub370e5a2017-08-16 13:24:58 -0400595
Lei Zhanga21d5932018-02-05 18:28:38 +0000596 {
597 // Retrieve the square annotation which has its AP stream already defined.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000598 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +0000599 ASSERT_TRUE(annot);
600 EXPECT_EQ(FPDF_ANNOT_SQUARE, FPDFAnnot_GetSubtype(annot.get()));
Jane Liu06462752017-06-27 16:41:14 -0400601
Lei Zhanga21d5932018-02-05 18:28:38 +0000602 // Check that updating the rectangle would succeed.
603 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
604 rect.left += 70.f;
605 rect.right += 70.f;
606 ASSERT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
607 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &new_rect));
608 EXPECT_EQ(rect.right, new_rect.right);
Jane Liu06462752017-06-27 16:41:14 -0400609
Lei Zhanga21d5932018-02-05 18:28:38 +0000610 // Check that updating the rectangle changes the square annotation's
611 // position.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000612 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000613 CompareBitmap(bitmap.get(), 612, 792, kMd5ModifiedSquare);
Lei Zhanga21d5932018-02-05 18:28:38 +0000614 }
Jane Liub370e5a2017-08-16 13:24:58 -0400615
Jane Liu06462752017-06-27 16:41:14 -0400616 UnloadPage(page);
617}
Jane Liu8ce58f52017-06-29 13:40:22 -0400618
Lei Zhangab41f252018-12-23 03:10:50 +0000619TEST_F(FPDFAnnotEmbedderTest, CountAttachmentPoints) {
Henrique Nakashima5098b252018-03-26 21:46:00 +0000620 // Open a file with multiline markup annotations.
621 ASSERT_TRUE(OpenDocument("annotation_markup_multiline_no_ap.pdf"));
622 FPDF_PAGE page = LoadPage(0);
623 ASSERT_TRUE(page);
624 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000625 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Henrique Nakashima5098b252018-03-26 21:46:00 +0000626 ASSERT_TRUE(annot);
627
628 // This is a three line annotation.
629 EXPECT_EQ(3u, FPDFAnnot_CountAttachmentPoints(annot.get()));
630 }
631 UnloadPage(page);
632
633 // null annotation should return 0
634 EXPECT_EQ(0u, FPDFAnnot_CountAttachmentPoints(nullptr));
635}
636
Lei Zhangab41f252018-12-23 03:10:50 +0000637TEST_F(FPDFAnnotEmbedderTest, RemoveAnnotation) {
Jane Liu8ce58f52017-06-29 13:40:22 -0400638 // Open a file with 3 annotations on its first page.
639 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
Tom Sepez507d0192018-11-07 16:37:51 +0000640 FPDF_PAGE page = LoadPageNoEvents(0);
Jane Liu8ce58f52017-06-29 13:40:22 -0400641 ASSERT_TRUE(page);
642 EXPECT_EQ(3, FPDFPage_GetAnnotCount(page));
643
Jane Liu0c6b07d2017-08-15 10:50:22 -0400644 FS_RECTF rect;
Jane Liu8ce58f52017-06-29 13:40:22 -0400645
Lei Zhanga21d5932018-02-05 18:28:38 +0000646 // Check that the annotations have the expected rectangle coordinates.
647 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000648 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000649 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
650 EXPECT_NEAR(86.1971f, rect.left, 0.001f);
651 }
Jane Liu8ce58f52017-06-29 13:40:22 -0400652
Lei Zhanga21d5932018-02-05 18:28:38 +0000653 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000654 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 1));
Lei Zhanga21d5932018-02-05 18:28:38 +0000655 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
656 EXPECT_NEAR(149.8127f, rect.left, 0.001f);
657 }
658
659 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000660 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +0000661 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
662 EXPECT_NEAR(351.8204f, rect.left, 0.001f);
663 }
Jane Liu8ce58f52017-06-29 13:40:22 -0400664
665 // Check that nothing happens when attempting to remove an annotation with an
666 // out-of-bound index.
667 EXPECT_FALSE(FPDFPage_RemoveAnnot(page, 4));
668 EXPECT_FALSE(FPDFPage_RemoveAnnot(page, -1));
669 EXPECT_EQ(3, FPDFPage_GetAnnotCount(page));
670
671 // Remove the second annotation.
672 EXPECT_TRUE(FPDFPage_RemoveAnnot(page, 1));
673 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
674 EXPECT_FALSE(FPDFPage_GetAnnot(page, 2));
675
676 // Save the document, closing the page and document.
677 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Tom Sepez507d0192018-11-07 16:37:51 +0000678 UnloadPageNoEvents(page);
Jane Liu8ce58f52017-06-29 13:40:22 -0400679
Dan Sinclair04e4dc82017-10-18 12:17:14 -0400680 // TODO(npm): VerifySavedRendering changes annot rect dimensions by 1??
Jane Liu8ce58f52017-06-29 13:40:22 -0400681 // Open the saved document.
682 std::string new_file = GetString();
683 FPDF_FILEACCESS file_access;
684 memset(&file_access, 0, sizeof(file_access));
685 file_access.m_FileLen = new_file.size();
686 file_access.m_GetBlock = GetBlockFromString;
687 file_access.m_Param = &new_file;
688 FPDF_DOCUMENT new_doc = FPDF_LoadCustomDocument(&file_access, nullptr);
689 ASSERT_TRUE(new_doc);
690 FPDF_PAGE new_page = FPDF_LoadPage(new_doc, 0);
691 ASSERT_TRUE(new_page);
692
693 // Check that the saved document has 2 annotations on the first page.
694 EXPECT_EQ(2, FPDFPage_GetAnnotCount(new_page));
695
Lei Zhanga21d5932018-02-05 18:28:38 +0000696 // Check that the remaining 2 annotations are the original 1st and 3rd ones
697 // by verifying their rectangle coordinates.
698 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000699 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(new_page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000700 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
701 EXPECT_NEAR(86.1971f, rect.left, 0.001f);
702 }
Jane Liu8ce58f52017-06-29 13:40:22 -0400703
Lei Zhanga21d5932018-02-05 18:28:38 +0000704 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000705 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(new_page, 1));
Lei Zhanga21d5932018-02-05 18:28:38 +0000706 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
707 EXPECT_NEAR(351.8204f, rect.left, 0.001f);
708 }
Jane Liubaa7ff42017-06-29 19:18:23 -0400709 FPDF_ClosePage(new_page);
710 FPDF_CloseDocument(new_doc);
711}
Jane Liu8ce58f52017-06-29 13:40:22 -0400712
Lei Zhang03e5e682019-09-16 19:45:55 +0000713// TODO(crbug.com/pdfium/11): Fix this test and enable.
714#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
715#define MAYBE_AddAndModifyPath DISABLED_AddAndModifyPath
716#else
717#define MAYBE_AddAndModifyPath AddAndModifyPath
718#endif
719TEST_F(FPDFAnnotEmbedderTest, MAYBE_AddAndModifyPath) {
Lei Zhange4cdac52019-04-30 16:45:57 +0000720#if defined(OS_MACOSX)
Lei Zhang4f556b82019-04-08 16:32:41 +0000721 static const char kMd5Original[] = "c35408717759562d1f8bf33d317483d2";
722 static const char kMd5ModifiedPath[] = "9059723a045e17478753d2f0eb33bc03";
723 static const char kMd5TwoPaths[] = "7eed0cfba780f1d4dd8068f717d3a6bf";
724 static const char kMd5NewAnnot[] = "1de8212d43b7066a6df042095c2aca61";
Lei Zhange67bcc72019-04-30 18:55:58 +0000725#elif defined(OS_WIN)
Lei Zhanga2b70732019-06-25 08:34:22 +0000726 static const char kMd5Original[] = "6aa001a77ec05d0f1b0d1d22e28744d4";
727 static const char kMd5ModifiedPath[] = "a7a8d675a6ddbcbdfecee65a33ba19e1";
728 static const char kMd5TwoPaths[] = "7c0bdd4552329704c47a7cce47edbbd6";
729 static const char kMd5NewAnnot[] = "3c48d492b4f62941fed0fb62f729f31e";
Jane Liubaa7ff42017-06-29 19:18:23 -0400730#else
Lei Zhanga2b70732019-06-25 08:34:22 +0000731 static const char kMd5Original[] = "b42cef463483e668eaf4055a65e4f1f5";
732 static const char kMd5ModifiedPath[] = "6ff77d6d1fec4ea571fabe0c7a19b517";
733 static const char kMd5TwoPaths[] = "ca37ad549e74ac5b359a055708f3e7b6";
734 static const char kMd5NewAnnot[] = "0d7a0e33fbf41ff7fa5d732ab2c5edff";
Jane Liubaa7ff42017-06-29 19:18:23 -0400735#endif
736
737 // Open a file with two annotations and load its first page.
738 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000739 FPDF_PAGE page = LoadPage(0);
Jane Liubaa7ff42017-06-29 19:18:23 -0400740 ASSERT_TRUE(page);
741 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
742
743 // Check that the page renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000744 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000745 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000746 CompareBitmap(bitmap.get(), 595, 842, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000747 }
Jane Liubaa7ff42017-06-29 19:18:23 -0400748
Lei Zhanga21d5932018-02-05 18:28:38 +0000749 {
750 // Retrieve the stamp annotation which has its AP stream already defined.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000751 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000752 ASSERT_TRUE(annot);
Jane Liubaa7ff42017-06-29 19:18:23 -0400753
Lei Zhanga21d5932018-02-05 18:28:38 +0000754 // Check that this annotation has one path object and retrieve it.
755 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000756 ASSERT_EQ(32, FPDFPage_CountObjects(page));
Lei Zhanga21d5932018-02-05 18:28:38 +0000757 FPDF_PAGEOBJECT path = FPDFAnnot_GetObject(annot.get(), 1);
758 EXPECT_FALSE(path);
759 path = FPDFAnnot_GetObject(annot.get(), 0);
760 EXPECT_EQ(FPDF_PAGEOBJ_PATH, FPDFPageObj_GetType(path));
761 EXPECT_TRUE(path);
Jane Liubaa7ff42017-06-29 19:18:23 -0400762
Lei Zhanga21d5932018-02-05 18:28:38 +0000763 // Modify the color of the path object.
Lei Zhang3475b482019-05-13 18:30:57 +0000764 EXPECT_TRUE(FPDFPageObj_SetStrokeColor(path, 0, 0, 0, 255));
Lei Zhanga21d5932018-02-05 18:28:38 +0000765 EXPECT_TRUE(FPDFAnnot_UpdateObject(annot.get(), path));
Jane Liubaa7ff42017-06-29 19:18:23 -0400766
Lei Zhanga21d5932018-02-05 18:28:38 +0000767 // Check that the page with the modified annotation renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000768 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000769 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000770 CompareBitmap(bitmap.get(), 595, 842, kMd5ModifiedPath);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000771 }
Jane Liu7a9a38b2017-07-11 13:47:37 -0400772
Lei Zhanga21d5932018-02-05 18:28:38 +0000773 // Add a second path object to the same annotation.
774 FPDF_PAGEOBJECT dot = FPDFPageObj_CreateNewPath(7, 84);
775 EXPECT_TRUE(FPDFPath_BezierTo(dot, 9, 86, 10, 87, 11, 88));
Lei Zhang3475b482019-05-13 18:30:57 +0000776 EXPECT_TRUE(FPDFPageObj_SetStrokeColor(dot, 255, 0, 0, 100));
777 EXPECT_TRUE(FPDFPageObj_SetStrokeWidth(dot, 14));
Lei Zhanga21d5932018-02-05 18:28:38 +0000778 EXPECT_TRUE(FPDFPath_SetDrawMode(dot, 0, 1));
779 EXPECT_TRUE(FPDFAnnot_AppendObject(annot.get(), dot));
780 EXPECT_EQ(2, FPDFAnnot_GetObjectCount(annot.get()));
Jane Liu7a9a38b2017-07-11 13:47:37 -0400781
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000782 // The object is in the annontation, not in the page, so the page object
783 // array should not change.
784 ASSERT_EQ(32, FPDFPage_CountObjects(page));
785
Lei Zhanga21d5932018-02-05 18:28:38 +0000786 // Check that the page with an annotation with two paths renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000787 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000788 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000789 CompareBitmap(bitmap.get(), 595, 842, kMd5TwoPaths);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000790 }
Jane Liu7a9a38b2017-07-11 13:47:37 -0400791
Lei Zhanga21d5932018-02-05 18:28:38 +0000792 // Delete the newly added path object.
793 EXPECT_TRUE(FPDFAnnot_RemoveObject(annot.get(), 1));
794 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000795 ASSERT_EQ(32, FPDFPage_CountObjects(page));
Lei Zhanga21d5932018-02-05 18:28:38 +0000796 }
Jane Liu7a9a38b2017-07-11 13:47:37 -0400797
798 // Check that the page renders the same as before.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000799 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000800 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000801 CompareBitmap(bitmap.get(), 595, 842, kMd5ModifiedPath);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000802 }
Jane Liubaa7ff42017-06-29 19:18:23 -0400803
Jane Liubaa7ff42017-06-29 19:18:23 -0400804 FS_RECTF rect;
Jane Liubaa7ff42017-06-29 19:18:23 -0400805
Lei Zhanga21d5932018-02-05 18:28:38 +0000806 {
807 // Create another stamp annotation and set its annotation rectangle.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000808 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP));
Lei Zhanga21d5932018-02-05 18:28:38 +0000809 ASSERT_TRUE(annot);
810 rect.left = 200.f;
811 rect.bottom = 400.f;
812 rect.right = 500.f;
813 rect.top = 600.f;
814 EXPECT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
Jane Liubaa7ff42017-06-29 19:18:23 -0400815
Lei Zhanga21d5932018-02-05 18:28:38 +0000816 // Add a new path to the annotation.
817 FPDF_PAGEOBJECT check = FPDFPageObj_CreateNewPath(200, 500);
818 EXPECT_TRUE(FPDFPath_LineTo(check, 300, 400));
819 EXPECT_TRUE(FPDFPath_LineTo(check, 500, 600));
820 EXPECT_TRUE(FPDFPath_MoveTo(check, 350, 550));
821 EXPECT_TRUE(FPDFPath_LineTo(check, 450, 450));
Lei Zhang3475b482019-05-13 18:30:57 +0000822 EXPECT_TRUE(FPDFPageObj_SetStrokeColor(check, 0, 255, 255, 180));
823 EXPECT_TRUE(FPDFPageObj_SetStrokeWidth(check, 8.35f));
Lei Zhanga21d5932018-02-05 18:28:38 +0000824 EXPECT_TRUE(FPDFPath_SetDrawMode(check, 0, 1));
825 EXPECT_TRUE(FPDFAnnot_AppendObject(annot.get(), check));
826 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
827
828 // Check that the annotation's bounding box came from its rectangle.
829 FS_RECTF new_rect;
830 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &new_rect));
831 EXPECT_EQ(rect.left, new_rect.left);
832 EXPECT_EQ(rect.bottom, new_rect.bottom);
833 EXPECT_EQ(rect.right, new_rect.right);
834 EXPECT_EQ(rect.top, new_rect.top);
835 }
Jane Liubaa7ff42017-06-29 19:18:23 -0400836
837 // Save the document, closing the page and document.
Jane Liubaa7ff42017-06-29 19:18:23 -0400838 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang75c81712018-02-08 17:22:39 +0000839 UnloadPage(page);
Jane Liubaa7ff42017-06-29 19:18:23 -0400840
841 // Open the saved document.
Lei Zhang0b494052019-01-31 21:41:15 +0000842 ASSERT_TRUE(OpenSavedDocument());
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000843 page = LoadSavedPage(0);
Lei Zhang4f556b82019-04-08 16:32:41 +0000844 VerifySavedRendering(page, 595, 842, kMd5NewAnnot);
Jane Liubaa7ff42017-06-29 19:18:23 -0400845
Jane Liu36567742017-07-06 11:13:35 -0400846 // Check that the document has a correct count of annotations and objects.
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000847 EXPECT_EQ(3, FPDFPage_GetAnnotCount(page));
Jane Liubaa7ff42017-06-29 19:18:23 -0400848
Lei Zhanga21d5932018-02-05 18:28:38 +0000849 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000850 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +0000851 ASSERT_TRUE(annot);
852 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
Jane Liubaa7ff42017-06-29 19:18:23 -0400853
Lei Zhanga21d5932018-02-05 18:28:38 +0000854 // Check that the new annotation's rectangle is as defined.
855 FS_RECTF new_rect;
856 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &new_rect));
857 EXPECT_EQ(rect.left, new_rect.left);
858 EXPECT_EQ(rect.bottom, new_rect.bottom);
859 EXPECT_EQ(rect.right, new_rect.right);
860 EXPECT_EQ(rect.top, new_rect.top);
861 }
862
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000863 CloseSavedPage(page);
Dan Sinclair04e4dc82017-10-18 12:17:14 -0400864 CloseSavedDocument();
Jane Liu8ce58f52017-06-29 13:40:22 -0400865}
Jane Liub137e752017-07-05 15:04:33 -0400866
Lei Zhangab41f252018-12-23 03:10:50 +0000867TEST_F(FPDFAnnotEmbedderTest, ModifyAnnotationFlags) {
Jane Liub137e752017-07-05 15:04:33 -0400868 // Open a file with an annotation and load its first page.
869 ASSERT_TRUE(OpenDocument("annotation_highlight_rollover_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000870 FPDF_PAGE page = LoadPage(0);
Jane Liub137e752017-07-05 15:04:33 -0400871 ASSERT_TRUE(page);
872
873 // Check that the page renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000874 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000875 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000876 CompareBitmap(bitmap.get(), 612, 792, "dc98f06da047bd8aabfa99562d2cbd1e");
877 }
Jane Liub137e752017-07-05 15:04:33 -0400878
Lei Zhanga21d5932018-02-05 18:28:38 +0000879 {
880 // Retrieve the annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000881 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000882 ASSERT_TRUE(annot);
Jane Liub137e752017-07-05 15:04:33 -0400883
Lei Zhanga21d5932018-02-05 18:28:38 +0000884 // Check that the original flag values are as expected.
885 int flags = FPDFAnnot_GetFlags(annot.get());
886 EXPECT_FALSE(flags & FPDF_ANNOT_FLAG_HIDDEN);
887 EXPECT_TRUE(flags & FPDF_ANNOT_FLAG_PRINT);
Jane Liub137e752017-07-05 15:04:33 -0400888
Lei Zhanga21d5932018-02-05 18:28:38 +0000889 // Set the HIDDEN flag.
890 flags |= FPDF_ANNOT_FLAG_HIDDEN;
891 EXPECT_TRUE(FPDFAnnot_SetFlags(annot.get(), flags));
892 flags = FPDFAnnot_GetFlags(annot.get());
893 EXPECT_TRUE(flags & FPDF_ANNOT_FLAG_HIDDEN);
894 EXPECT_TRUE(flags & FPDF_ANNOT_FLAG_PRINT);
Jane Liub137e752017-07-05 15:04:33 -0400895
Lei Zhanga21d5932018-02-05 18:28:38 +0000896 // Check that the page renders correctly without rendering the annotation.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000897 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000898 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000899 CompareBitmap(bitmap.get(), 612, 792, "1940568c9ba33bac5d0b1ee9558c76b3");
900 }
Jane Liub137e752017-07-05 15:04:33 -0400901
Lei Zhanga21d5932018-02-05 18:28:38 +0000902 // Unset the HIDDEN flag.
903 EXPECT_TRUE(FPDFAnnot_SetFlags(annot.get(), FPDF_ANNOT_FLAG_NONE));
904 EXPECT_FALSE(FPDFAnnot_GetFlags(annot.get()));
905 flags &= ~FPDF_ANNOT_FLAG_HIDDEN;
906 EXPECT_TRUE(FPDFAnnot_SetFlags(annot.get(), flags));
907 flags = FPDFAnnot_GetFlags(annot.get());
908 EXPECT_FALSE(flags & FPDF_ANNOT_FLAG_HIDDEN);
909 EXPECT_TRUE(flags & FPDF_ANNOT_FLAG_PRINT);
Jane Liub137e752017-07-05 15:04:33 -0400910
Lei Zhanga21d5932018-02-05 18:28:38 +0000911 // Check that the page renders correctly as before.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000912 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000913 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000914 CompareBitmap(bitmap.get(), 612, 792, "dc98f06da047bd8aabfa99562d2cbd1e");
915 }
Lei Zhanga21d5932018-02-05 18:28:38 +0000916 }
Jane Liub137e752017-07-05 15:04:33 -0400917
Jane Liub137e752017-07-05 15:04:33 -0400918 UnloadPage(page);
919}
Jane Liu36567742017-07-06 11:13:35 -0400920
Lei Zhang03e5e682019-09-16 19:45:55 +0000921// TODO(crbug.com/pdfium/11): Fix this test and enable.
922#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
923#define MAYBE_AddAndModifyImage DISABLED_AddAndModifyImage
924#else
925#define MAYBE_AddAndModifyImage AddAndModifyImage
926#endif
927TEST_F(FPDFAnnotEmbedderTest, MAYBE_AddAndModifyImage) {
Lei Zhange4cdac52019-04-30 16:45:57 +0000928#if defined(OS_MACOSX)
Lei Zhang4f556b82019-04-08 16:32:41 +0000929 static const char kMd5Original[] = "c35408717759562d1f8bf33d317483d2";
930 static const char kMd5NewImage[] = "ff012f5697436dfcaec25b32d1333596";
931 static const char kMd5ModifiedImage[] = "86cf8cb2755a7a2046a543e66d9c1e61";
Lei Zhange67bcc72019-04-30 18:55:58 +0000932#elif defined(OS_WIN)
Lei Zhanga2b70732019-06-25 08:34:22 +0000933 static const char kMd5Original[] = "6aa001a77ec05d0f1b0d1d22e28744d4";
934 static const char kMd5NewImage[] = "3d77d06a971bcb9fb54db082f1082c8b";
935 static const char kMd5ModifiedImage[] = "dc4f4afc26c345418330d31c065020e1";
Jane Liu36567742017-07-06 11:13:35 -0400936#else
Lei Zhanga2b70732019-06-25 08:34:22 +0000937 static const char kMd5Original[] = "b42cef463483e668eaf4055a65e4f1f5";
938 static const char kMd5NewImage[] = "528e6243dc29d54f36b61e0d3287d935";
939 static const char kMd5ModifiedImage[] = "6d9e59f3e57a1ff82fb258356b7eb731";
Jane Liu36567742017-07-06 11:13:35 -0400940#endif
941
942 // Open a file with two annotations and load its first page.
943 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000944 FPDF_PAGE page = LoadPage(0);
Jane Liu36567742017-07-06 11:13:35 -0400945 ASSERT_TRUE(page);
946 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
947
948 // Check that the page renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000949 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000950 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000951 CompareBitmap(bitmap.get(), 595, 842, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000952 }
Jane Liu36567742017-07-06 11:13:35 -0400953
Jane Liu36567742017-07-06 11:13:35 -0400954 constexpr int kBitmapSize = 200;
Lei Zhanga21d5932018-02-05 18:28:38 +0000955 FPDF_BITMAP image_bitmap;
956
957 {
958 // Create a stamp annotation and set its annotation rectangle.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000959 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP));
Lei Zhanga21d5932018-02-05 18:28:38 +0000960 ASSERT_TRUE(annot);
961 FS_RECTF rect;
962 rect.left = 200.f;
963 rect.bottom = 600.f;
964 rect.right = 400.f;
965 rect.top = 800.f;
966 EXPECT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
967
968 // Add a solid-color translucent image object to the new annotation.
969 image_bitmap = FPDFBitmap_Create(kBitmapSize, kBitmapSize, 1);
970 FPDFBitmap_FillRect(image_bitmap, 0, 0, kBitmapSize, kBitmapSize,
971 0xeeeecccc);
972 EXPECT_EQ(kBitmapSize, FPDFBitmap_GetWidth(image_bitmap));
973 EXPECT_EQ(kBitmapSize, FPDFBitmap_GetHeight(image_bitmap));
974 FPDF_PAGEOBJECT image_object = FPDFPageObj_NewImageObj(document());
975 ASSERT_TRUE(FPDFImageObj_SetBitmap(&page, 0, image_object, image_bitmap));
976 ASSERT_TRUE(FPDFImageObj_SetMatrix(image_object, kBitmapSize, 0, 0,
977 kBitmapSize, 0, 0));
978 FPDFPageObj_Transform(image_object, 1, 0, 0, 1, 200, 600);
979 EXPECT_TRUE(FPDFAnnot_AppendObject(annot.get(), image_object));
980 }
Jane Liu36567742017-07-06 11:13:35 -0400981
982 // Check that the page renders correctly with the new image object.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000983 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000984 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000985 CompareBitmap(bitmap.get(), 595, 842, kMd5NewImage);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000986 }
Jane Liu36567742017-07-06 11:13:35 -0400987
Lei Zhanga21d5932018-02-05 18:28:38 +0000988 {
989 // Retrieve the newly added stamp annotation and its image object.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000990 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +0000991 ASSERT_TRUE(annot);
992 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
993 FPDF_PAGEOBJECT image_object = FPDFAnnot_GetObject(annot.get(), 0);
994 EXPECT_EQ(FPDF_PAGEOBJ_IMAGE, FPDFPageObj_GetType(image_object));
Jane Liu36567742017-07-06 11:13:35 -0400995
Lei Zhanga21d5932018-02-05 18:28:38 +0000996 // Modify the image in the new annotation.
997 FPDFBitmap_FillRect(image_bitmap, 0, 0, kBitmapSize, kBitmapSize,
998 0xff000000);
999 ASSERT_TRUE(FPDFImageObj_SetBitmap(&page, 0, image_object, image_bitmap));
1000 EXPECT_TRUE(FPDFAnnot_UpdateObject(annot.get(), image_object));
1001 }
Jane Liu36567742017-07-06 11:13:35 -04001002
1003 // Save the document, closing the page and document.
1004 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang75c81712018-02-08 17:22:39 +00001005 UnloadPage(page);
Dan Sinclair04e4dc82017-10-18 12:17:14 -04001006 FPDFBitmap_Destroy(image_bitmap);
Jane Liu36567742017-07-06 11:13:35 -04001007
1008 // Test that the saved document renders the modified image object correctly.
Lei Zhang4f556b82019-04-08 16:32:41 +00001009 VerifySavedDocument(595, 842, kMd5ModifiedImage);
Jane Liu36567742017-07-06 11:13:35 -04001010}
1011
Lei Zhang03e5e682019-09-16 19:45:55 +00001012// TODO(crbug.com/pdfium/11): Fix this test and enable.
1013#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
1014#define MAYBE_AddAndModifyText DISABLED_AddAndModifyText
1015#else
1016#define MAYBE_AddAndModifyText AddAndModifyText
1017#endif
1018TEST_F(FPDFAnnotEmbedderTest, MAYBE_AddAndModifyText) {
Lei Zhange4cdac52019-04-30 16:45:57 +00001019#if defined(OS_MACOSX)
Lei Zhang4f556b82019-04-08 16:32:41 +00001020 static const char kMd5Original[] = "c35408717759562d1f8bf33d317483d2";
1021 static const char kMd5NewText[] = "60031c1b0330cf1e1575f7d46687d429";
1022 static const char kMd5ModifiedText[] = "79f5cfb0b07caaf936f65f6a7a57ce77";
Lei Zhange67bcc72019-04-30 18:55:58 +00001023#elif defined(OS_WIN)
Lei Zhanga2b70732019-06-25 08:34:22 +00001024 static const char kMd5Original[] = "6aa001a77ec05d0f1b0d1d22e28744d4";
1025 static const char kMd5NewText[] = "204cc01749a70b8afc246a4ca33c7eb6";
1026 static const char kMd5ModifiedText[] = "641261a45e8dfd68c89b80bfd237660d";
Jane Liu36567742017-07-06 11:13:35 -04001027#else
Lei Zhanga2b70732019-06-25 08:34:22 +00001028 static const char kMd5Original[] = "b42cef463483e668eaf4055a65e4f1f5";
1029 static const char kMd5NewText[] = "00197ad6206f763febad5719e5935306";
1030 static const char kMd5ModifiedText[] = "85853bc0aaa5a4e3af04e58b9cbfff23";
Jane Liu36567742017-07-06 11:13:35 -04001031#endif
1032
1033 // Open a file with two annotations and load its first page.
1034 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001035 FPDF_PAGE page = LoadPage(0);
Jane Liu36567742017-07-06 11:13:35 -04001036 ASSERT_TRUE(page);
1037 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
1038
1039 // Check that the page renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +00001040 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001041 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +00001042 CompareBitmap(bitmap.get(), 595, 842, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +00001043 }
Jane Liu36567742017-07-06 11:13:35 -04001044
Lei Zhanga21d5932018-02-05 18:28:38 +00001045 {
1046 // Create a stamp annotation and set its annotation rectangle.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001047 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP));
Lei Zhanga21d5932018-02-05 18:28:38 +00001048 ASSERT_TRUE(annot);
1049 FS_RECTF rect;
1050 rect.left = 200.f;
1051 rect.bottom = 550.f;
1052 rect.right = 450.f;
1053 rect.top = 650.f;
1054 EXPECT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
Jane Liu36567742017-07-06 11:13:35 -04001055
Lei Zhanga21d5932018-02-05 18:28:38 +00001056 // Add a translucent text object to the new annotation.
1057 FPDF_PAGEOBJECT text_object =
1058 FPDFPageObj_NewTextObj(document(), "Arial", 12.0f);
1059 EXPECT_TRUE(text_object);
Lei Zhangf0f67682019-04-08 17:03:21 +00001060 ScopedFPDFWideString text =
Lei Zhanga21d5932018-02-05 18:28:38 +00001061 GetFPDFWideString(L"I'm a translucent text laying on other text.");
1062 EXPECT_TRUE(FPDFText_SetText(text_object, text.get()));
Lei Zhang3475b482019-05-13 18:30:57 +00001063 EXPECT_TRUE(FPDFPageObj_SetFillColor(text_object, 0, 0, 255, 150));
Lei Zhanga21d5932018-02-05 18:28:38 +00001064 FPDFPageObj_Transform(text_object, 1, 0, 0, 1, 200, 600);
1065 EXPECT_TRUE(FPDFAnnot_AppendObject(annot.get(), text_object));
1066 }
Jane Liu36567742017-07-06 11:13:35 -04001067
1068 // Check that the page renders correctly with the new text object.
Lei Zhangc113c7a2018-02-12 14:58:44 +00001069 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001070 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +00001071 CompareBitmap(bitmap.get(), 595, 842, kMd5NewText);
Lei Zhangc113c7a2018-02-12 14:58:44 +00001072 }
Jane Liu36567742017-07-06 11:13:35 -04001073
Lei Zhanga21d5932018-02-05 18:28:38 +00001074 {
1075 // Retrieve the newly added stamp annotation and its text object.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001076 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +00001077 ASSERT_TRUE(annot);
1078 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
1079 FPDF_PAGEOBJECT text_object = FPDFAnnot_GetObject(annot.get(), 0);
1080 EXPECT_EQ(FPDF_PAGEOBJ_TEXT, FPDFPageObj_GetType(text_object));
Jane Liu36567742017-07-06 11:13:35 -04001081
Lei Zhanga21d5932018-02-05 18:28:38 +00001082 // Modify the text in the new annotation.
Lei Zhangf0f67682019-04-08 17:03:21 +00001083 ScopedFPDFWideString new_text = GetFPDFWideString(L"New text!");
Lei Zhanga21d5932018-02-05 18:28:38 +00001084 EXPECT_TRUE(FPDFText_SetText(text_object, new_text.get()));
1085 EXPECT_TRUE(FPDFAnnot_UpdateObject(annot.get(), text_object));
1086 }
Jane Liu36567742017-07-06 11:13:35 -04001087
1088 // Check that the page renders correctly with the modified text object.
Lei Zhangc113c7a2018-02-12 14:58:44 +00001089 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001090 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +00001091 CompareBitmap(bitmap.get(), 595, 842, kMd5ModifiedText);
Lei Zhangc113c7a2018-02-12 14:58:44 +00001092 }
Jane Liu36567742017-07-06 11:13:35 -04001093
1094 // Remove the new annotation, and check that the page renders as before.
1095 EXPECT_TRUE(FPDFPage_RemoveAnnot(page, 2));
Lei Zhangc113c7a2018-02-12 14:58:44 +00001096 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001097 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +00001098 CompareBitmap(bitmap.get(), 595, 842, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +00001099 }
Jane Liu36567742017-07-06 11:13:35 -04001100
1101 UnloadPage(page);
1102}
Jane Liu2e1a32b2017-07-06 12:01:25 -04001103
Lei Zhang03e5e682019-09-16 19:45:55 +00001104// TODO(crbug.com/pdfium/11): Fix this test and enable.
1105#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
1106#define MAYBE_GetSetStringValue DISABLED_GetSetStringValue
1107#else
1108#define MAYBE_GetSetStringValue GetSetStringValue
1109#endif
1110TEST_F(FPDFAnnotEmbedderTest, MAYBE_GetSetStringValue) {
Jane Liu2e1a32b2017-07-06 12:01:25 -04001111 // Open a file with four annotations and load its first page.
1112 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001113 FPDF_PAGE page = LoadPage(0);
Jane Liu2e1a32b2017-07-06 12:01:25 -04001114 ASSERT_TRUE(page);
1115
Lei Zhang4f556b82019-04-08 16:32:41 +00001116 static const wchar_t kNewDate[] = L"D:201706282359Z00'00'";
Jane Liu2e1a32b2017-07-06 12:01:25 -04001117
Lei Zhanga21d5932018-02-05 18:28:38 +00001118 {
1119 // Retrieve the first annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001120 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001121 ASSERT_TRUE(annot);
1122
1123 // Check that a non-existent key does not exist.
1124 EXPECT_FALSE(FPDFAnnot_HasKey(annot.get(), "none"));
1125
1126 // Check that the string value of a non-string dictionary entry is empty.
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001127 EXPECT_TRUE(FPDFAnnot_HasKey(annot.get(), pdfium::annotation::kAP));
Lei Zhanga21d5932018-02-05 18:28:38 +00001128 EXPECT_EQ(FPDF_OBJECT_REFERENCE,
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001129 FPDFAnnot_GetValueType(annot.get(), pdfium::annotation::kAP));
1130 EXPECT_EQ(2u, FPDFAnnot_GetStringValue(annot.get(), pdfium::annotation::kAP,
1131 nullptr, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001132
1133 // Check that the string value of the hash is correct.
Lei Zhang4f556b82019-04-08 16:32:41 +00001134 static const char kHashKey[] = "AAPL:Hash";
Lei Zhanga21d5932018-02-05 18:28:38 +00001135 EXPECT_EQ(FPDF_OBJECT_NAME, FPDFAnnot_GetValueType(annot.get(), kHashKey));
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001136 unsigned long length_bytes =
Lei Zhanga21d5932018-02-05 18:28:38 +00001137 FPDFAnnot_GetStringValue(annot.get(), kHashKey, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001138 ASSERT_EQ(66u, length_bytes);
1139 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
1140 EXPECT_EQ(66u, FPDFAnnot_GetStringValue(annot.get(), kHashKey, buf.data(),
1141 length_bytes));
1142 EXPECT_EQ(L"395fbcb98d558681742f30683a62a2ad",
1143 GetPlatformWString(buf.data()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001144
1145 // Check that the string value of the modified date is correct.
1146 EXPECT_EQ(FPDF_OBJECT_NAME, FPDFAnnot_GetValueType(annot.get(), kHashKey));
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001147 length_bytes = FPDFAnnot_GetStringValue(annot.get(), pdfium::annotation::kM,
1148 nullptr, 0);
1149 ASSERT_EQ(44u, length_bytes);
1150 buf = GetFPDFWideStringBuffer(length_bytes);
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001151 EXPECT_EQ(44u, FPDFAnnot_GetStringValue(annot.get(), pdfium::annotation::kM,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001152 buf.data(), length_bytes));
1153 EXPECT_EQ(L"D:201706071721Z00'00'", GetPlatformWString(buf.data()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001154
1155 // Update the date entry for the annotation.
Lei Zhangf0f67682019-04-08 17:03:21 +00001156 ScopedFPDFWideString text = GetFPDFWideString(kNewDate);
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001157 EXPECT_TRUE(FPDFAnnot_SetStringValue(annot.get(), pdfium::annotation::kM,
1158 text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001159 }
Jane Liu2e1a32b2017-07-06 12:01:25 -04001160
1161 // Save the document, closing the page and document.
Jane Liu2e1a32b2017-07-06 12:01:25 -04001162 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang75c81712018-02-08 17:22:39 +00001163 UnloadPage(page);
Jane Liu2e1a32b2017-07-06 12:01:25 -04001164
Lei Zhange4cdac52019-04-30 16:45:57 +00001165#if defined(OS_MACOSX)
Lei Zhang4f556b82019-04-08 16:32:41 +00001166 static const char kMd5[] = "4d64e61c9c0f8c60ab3cc3234bb73b1c";
Lei Zhange67bcc72019-04-30 18:55:58 +00001167#elif defined(OS_WIN)
Lei Zhanga2b70732019-06-25 08:34:22 +00001168 static const char kMd5[] = "20b612ebd46babcb44c48c903e2c5a48";
Jane Liu2e1a32b2017-07-06 12:01:25 -04001169#else
Lei Zhanga2b70732019-06-25 08:34:22 +00001170 static const char kMd5[] = "1d7bea2042c6fea0558ff2aef05811b5";
Jane Liu2e1a32b2017-07-06 12:01:25 -04001171#endif
Dan Sinclair971a6742018-03-28 19:23:25 +00001172
1173 // Open the saved annotation.
Lei Zhang0b494052019-01-31 21:41:15 +00001174 ASSERT_TRUE(OpenSavedDocument());
Henrique Nakashima8baea3c2017-11-10 20:27:23 +00001175 page = LoadSavedPage(0);
Lei Zhang4f556b82019-04-08 16:32:41 +00001176 VerifySavedRendering(page, 595, 842, kMd5);
Lei Zhanga21d5932018-02-05 18:28:38 +00001177 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001178 ScopedFPDFAnnotation new_annot(FPDFPage_GetAnnot(page, 0));
Jane Liu2e1a32b2017-07-06 12:01:25 -04001179
Lei Zhanga21d5932018-02-05 18:28:38 +00001180 // Check that the string value of the modified date is the newly-set value.
1181 EXPECT_EQ(FPDF_OBJECT_STRING,
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001182 FPDFAnnot_GetValueType(new_annot.get(), pdfium::annotation::kM));
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001183 unsigned long length_bytes = FPDFAnnot_GetStringValue(
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001184 new_annot.get(), pdfium::annotation::kM, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001185 ASSERT_EQ(44u, length_bytes);
1186 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001187 EXPECT_EQ(44u,
1188 FPDFAnnot_GetStringValue(new_annot.get(), pdfium::annotation::kM,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001189 buf.data(), length_bytes));
1190 EXPECT_EQ(kNewDate, GetPlatformWString(buf.data()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001191 }
Jane Liu2e1a32b2017-07-06 12:01:25 -04001192
Henrique Nakashima8baea3c2017-11-10 20:27:23 +00001193 CloseSavedPage(page);
Dan Sinclair04e4dc82017-10-18 12:17:14 -04001194 CloseSavedDocument();
Jane Liu2e1a32b2017-07-06 12:01:25 -04001195}
Diana Gage7e0c05d2017-07-19 17:33:33 -07001196
rycsmith3e785602019-03-05 21:48:36 +00001197TEST_F(FPDFAnnotEmbedderTest, GetNumberValue) {
Mansi Awasthi0b5da672020-01-23 18:17:18 +00001198 // Open a file with four text annotations and load its first page.
rycsmith3e785602019-03-05 21:48:36 +00001199 ASSERT_TRUE(OpenDocument("text_form_multiple.pdf"));
1200 FPDF_PAGE page = LoadPage(0);
1201 ASSERT_TRUE(page);
1202 {
1203 // First two annotations do not have "MaxLen" attribute.
1204 for (int i = 0; i < 2; i++) {
1205 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, i));
1206 ASSERT_TRUE(annot);
1207
1208 // Verify that no "MaxLen" key present.
1209 EXPECT_FALSE(FPDFAnnot_HasKey(annot.get(), "MaxLen"));
1210
1211 float value;
1212 EXPECT_FALSE(FPDFAnnot_GetNumberValue(annot.get(), "MaxLen", &value));
1213 }
1214
1215 // Annotation in index 2 has "MaxLen" of 10.
1216 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
1217 ASSERT_TRUE(annot);
1218
1219 // Verify that "MaxLen" key present.
1220 EXPECT_TRUE(FPDFAnnot_HasKey(annot.get(), "MaxLen"));
1221
1222 float value;
1223 EXPECT_TRUE(FPDFAnnot_GetNumberValue(annot.get(), "MaxLen", &value));
1224 EXPECT_FLOAT_EQ(10.0f, value);
1225
1226 // Check bad inputs.
1227 EXPECT_FALSE(FPDFAnnot_GetNumberValue(nullptr, "MaxLen", &value));
1228 EXPECT_FALSE(FPDFAnnot_GetNumberValue(annot.get(), nullptr, &value));
1229 EXPECT_FALSE(FPDFAnnot_GetNumberValue(annot.get(), "MaxLen", nullptr));
1230 // Ask for key that exists but is not a number.
1231 EXPECT_FALSE(FPDFAnnot_GetNumberValue(annot.get(), "V", &value));
1232 }
1233
1234 UnloadPage(page);
1235}
1236
Lei Zhangab41f252018-12-23 03:10:50 +00001237TEST_F(FPDFAnnotEmbedderTest, GetSetAP) {
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001238 // Open a file with four annotations and load its first page.
1239 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001240 FPDF_PAGE page = LoadPage(0);
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001241 ASSERT_TRUE(page);
1242
Lei Zhanga21d5932018-02-05 18:28:38 +00001243 {
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001244 static const char kMd5NormalAP[] = "be903df0343fd774fadab9c8900cdf4a";
1245 static constexpr size_t kExpectNormalAPLength = 73970;
1246
Lei Zhanga21d5932018-02-05 18:28:38 +00001247 // Retrieve the first annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001248 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001249 ASSERT_TRUE(annot);
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001250
Lei Zhanga21d5932018-02-05 18:28:38 +00001251 // Check that the string value of an AP returns the expected length.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001252 unsigned long normal_length_bytes = FPDFAnnot_GetAP(
Lei Zhanga21d5932018-02-05 18:28:38 +00001253 annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001254 ASSERT_EQ(kExpectNormalAPLength, normal_length_bytes);
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001255
Lei Zhanga21d5932018-02-05 18:28:38 +00001256 // Check that the string value of an AP is not returned if the buffer is too
1257 // small. The result buffer should be overwritten with an empty string.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001258 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(normal_length_bytes);
1259 // Write in the buffer to verify it's not overwritten.
1260 memcpy(buf.data(), "abcdefgh", 8);
1261 EXPECT_EQ(kExpectNormalAPLength,
Lei Zhanga21d5932018-02-05 18:28:38 +00001262 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001263 buf.data(), normal_length_bytes - 1));
1264 EXPECT_EQ(0, memcmp(buf.data(), "abcdefgh", 8));
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001265
Lei Zhanga21d5932018-02-05 18:28:38 +00001266 // Check that the string value of an AP is returned through a buffer that is
1267 // the right size.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001268 EXPECT_EQ(kExpectNormalAPLength,
Lei Zhanga21d5932018-02-05 18:28:38 +00001269 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001270 buf.data(), normal_length_bytes));
1271 EXPECT_EQ(kMd5NormalAP,
1272 GenerateMD5Base16(reinterpret_cast<uint8_t*>(buf.data()),
1273 normal_length_bytes));
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001274
Lei Zhanga21d5932018-02-05 18:28:38 +00001275 // Check that the string value of an AP is returned through a buffer that is
1276 // larger than necessary.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001277 buf = GetFPDFWideStringBuffer(normal_length_bytes + 2);
1278 EXPECT_EQ(kExpectNormalAPLength,
Lei Zhanga21d5932018-02-05 18:28:38 +00001279 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001280 buf.data(), normal_length_bytes + 2));
1281 EXPECT_EQ(kMd5NormalAP,
1282 GenerateMD5Base16(reinterpret_cast<uint8_t*>(buf.data()),
1283 normal_length_bytes));
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001284
Lei Zhanga21d5932018-02-05 18:28:38 +00001285 // Check that getting an AP for a mode that does not have an AP returns an
1286 // empty string.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001287 unsigned long rollover_length_bytes = FPDFAnnot_GetAP(
Lei Zhanga21d5932018-02-05 18:28:38 +00001288 annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001289 ASSERT_EQ(2u, rollover_length_bytes);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001290
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001291 buf = GetFPDFWideStringBuffer(1000);
Lei Zhanga21d5932018-02-05 18:28:38 +00001292 EXPECT_EQ(2u,
1293 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001294 buf.data(), 1000));
1295 EXPECT_EQ(L"", GetPlatformWString(buf.data()));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001296
Lei Zhanga21d5932018-02-05 18:28:38 +00001297 // Check that setting the AP for an invalid appearance mode fails.
Lei Zhangf0f67682019-04-08 17:03:21 +00001298 ScopedFPDFWideString ap_text = GetFPDFWideString(L"new test ap");
Lei Zhang4f556b82019-04-08 16:32:41 +00001299 EXPECT_FALSE(FPDFAnnot_SetAP(annot.get(), -1, ap_text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001300 EXPECT_FALSE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_COUNT,
Lei Zhang4f556b82019-04-08 16:32:41 +00001301 ap_text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001302 EXPECT_FALSE(FPDFAnnot_SetAP(
Lei Zhang4f556b82019-04-08 16:32:41 +00001303 annot.get(), FPDF_ANNOT_APPEARANCEMODE_COUNT + 1, ap_text.get()));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001304
Lei Zhanga21d5932018-02-05 18:28:38 +00001305 // Set the AP correctly now.
1306 EXPECT_TRUE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang4f556b82019-04-08 16:32:41 +00001307 ap_text.get()));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001308
Lei Zhanga21d5932018-02-05 18:28:38 +00001309 // Check that the new annotation value is equal to the value we just set.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001310 rollover_length_bytes = FPDFAnnot_GetAP(
Lei Zhanga21d5932018-02-05 18:28:38 +00001311 annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001312 ASSERT_EQ(24u, rollover_length_bytes);
1313 buf = GetFPDFWideStringBuffer(rollover_length_bytes);
Lei Zhanga21d5932018-02-05 18:28:38 +00001314 EXPECT_EQ(24u,
1315 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001316 buf.data(), rollover_length_bytes));
1317 EXPECT_EQ(L"new test ap", GetPlatformWString(buf.data()));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001318
Lei Zhanga21d5932018-02-05 18:28:38 +00001319 // Check that the Normal AP was not touched when the Rollover AP was set.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001320 buf = GetFPDFWideStringBuffer(normal_length_bytes);
1321 EXPECT_EQ(kExpectNormalAPLength,
Lei Zhanga21d5932018-02-05 18:28:38 +00001322 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001323 buf.data(), normal_length_bytes));
1324 EXPECT_EQ(kMd5NormalAP,
1325 GenerateMD5Base16(reinterpret_cast<uint8_t*>(buf.data()),
1326 normal_length_bytes));
Lei Zhanga21d5932018-02-05 18:28:38 +00001327 }
Henrique Nakashima5970a472018-01-11 22:40:59 +00001328
1329 // Save the modified document, then reopen it.
Henrique Nakashima5970a472018-01-11 22:40:59 +00001330 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang75c81712018-02-08 17:22:39 +00001331 UnloadPage(page);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001332
Lei Zhang0b494052019-01-31 21:41:15 +00001333 ASSERT_TRUE(OpenSavedDocument());
Henrique Nakashima5970a472018-01-11 22:40:59 +00001334 page = LoadSavedPage(0);
Lei Zhanga21d5932018-02-05 18:28:38 +00001335 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001336 ScopedFPDFAnnotation new_annot(FPDFPage_GetAnnot(page, 0));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001337
Lei Zhanga21d5932018-02-05 18:28:38 +00001338 // Check that the new annotation value is equal to the value we set before
1339 // saving.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001340 unsigned long rollover_length_bytes = FPDFAnnot_GetAP(
Lei Zhanga21d5932018-02-05 18:28:38 +00001341 new_annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001342 ASSERT_EQ(24u, rollover_length_bytes);
1343 std::vector<FPDF_WCHAR> buf =
1344 GetFPDFWideStringBuffer(rollover_length_bytes);
Lei Zhanga21d5932018-02-05 18:28:38 +00001345 EXPECT_EQ(24u, FPDFAnnot_GetAP(new_annot.get(),
1346 FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001347 buf.data(), rollover_length_bytes));
1348 EXPECT_EQ(L"new test ap", GetPlatformWString(buf.data()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001349 }
Henrique Nakashima5970a472018-01-11 22:40:59 +00001350
1351 // Close saved document.
Henrique Nakashima5970a472018-01-11 22:40:59 +00001352 CloseSavedPage(page);
1353 CloseSavedDocument();
1354}
1355
Lei Zhangab41f252018-12-23 03:10:50 +00001356TEST_F(FPDFAnnotEmbedderTest, RemoveOptionalAP) {
Henrique Nakashima5970a472018-01-11 22:40:59 +00001357 // Open a file with four annotations and load its first page.
1358 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001359 FPDF_PAGE page = LoadPage(0);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001360 ASSERT_TRUE(page);
1361
Lei Zhanga21d5932018-02-05 18:28:38 +00001362 {
1363 // Retrieve the first annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001364 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001365 ASSERT_TRUE(annot);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001366
Lei Zhanga21d5932018-02-05 18:28:38 +00001367 // Set Down AP. Normal AP is already set.
Lei Zhangf0f67682019-04-08 17:03:21 +00001368 ScopedFPDFWideString ap_text = GetFPDFWideString(L"new test ap");
Lei Zhanga21d5932018-02-05 18:28:38 +00001369 EXPECT_TRUE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
Lei Zhang4f556b82019-04-08 16:32:41 +00001370 ap_text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001371 EXPECT_EQ(73970u,
1372 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
1373 nullptr, 0));
1374 EXPECT_EQ(24u, FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
1375 nullptr, 0));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001376
Lei Zhanga21d5932018-02-05 18:28:38 +00001377 // Check that setting the Down AP to null removes the Down entry but keeps
1378 // Normal intact.
1379 EXPECT_TRUE(
1380 FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN, nullptr));
1381 EXPECT_EQ(73970u,
1382 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
1383 nullptr, 0));
1384 EXPECT_EQ(2u, FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
1385 nullptr, 0));
1386 }
Henrique Nakashima5970a472018-01-11 22:40:59 +00001387
Lei Zhang75c81712018-02-08 17:22:39 +00001388 UnloadPage(page);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001389}
1390
Lei Zhangab41f252018-12-23 03:10:50 +00001391TEST_F(FPDFAnnotEmbedderTest, RemoveRequiredAP) {
Henrique Nakashima5970a472018-01-11 22:40:59 +00001392 // Open a file with four annotations and load its first page.
1393 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001394 FPDF_PAGE page = LoadPage(0);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001395 ASSERT_TRUE(page);
1396
Lei Zhanga21d5932018-02-05 18:28:38 +00001397 {
1398 // Retrieve the first annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001399 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001400 ASSERT_TRUE(annot);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001401
Lei Zhanga21d5932018-02-05 18:28:38 +00001402 // Set Down AP. Normal AP is already set.
Lei Zhangf0f67682019-04-08 17:03:21 +00001403 ScopedFPDFWideString ap_text = GetFPDFWideString(L"new test ap");
Lei Zhanga21d5932018-02-05 18:28:38 +00001404 EXPECT_TRUE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
Lei Zhang4f556b82019-04-08 16:32:41 +00001405 ap_text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001406 EXPECT_EQ(73970u,
1407 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
1408 nullptr, 0));
1409 EXPECT_EQ(24u, FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
1410 nullptr, 0));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001411
Lei Zhanga21d5932018-02-05 18:28:38 +00001412 // Check that setting the Normal AP to null removes the whole AP dictionary.
1413 EXPECT_TRUE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
1414 nullptr));
1415 EXPECT_EQ(2u, FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
1416 nullptr, 0));
1417 EXPECT_EQ(2u, FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
1418 nullptr, 0));
1419 }
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001420
Lei Zhang75c81712018-02-08 17:22:39 +00001421 UnloadPage(page);
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001422}
1423
Lei Zhangab41f252018-12-23 03:10:50 +00001424TEST_F(FPDFAnnotEmbedderTest, ExtractLinkedAnnotations) {
Jane Liu300bb272017-08-21 14:37:53 -04001425 // Open a file with annotations and load its first page.
1426 ASSERT_TRUE(OpenDocument("annotation_highlight_square_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001427 FPDF_PAGE page = LoadPage(0);
Jane Liu300bb272017-08-21 14:37:53 -04001428 ASSERT_TRUE(page);
Jane Liud1ed1ce2017-08-24 12:31:10 -04001429 EXPECT_EQ(-1, FPDFPage_GetAnnotIndex(page, nullptr));
Jane Liu300bb272017-08-21 14:37:53 -04001430
Lei Zhanga21d5932018-02-05 18:28:38 +00001431 {
1432 // Retrieve the highlight annotation which has its popup defined.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001433 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001434 ASSERT_TRUE(annot);
1435 EXPECT_EQ(FPDF_ANNOT_HIGHLIGHT, FPDFAnnot_GetSubtype(annot.get()));
1436 EXPECT_EQ(0, FPDFPage_GetAnnotIndex(page, annot.get()));
Lei Zhang4f556b82019-04-08 16:32:41 +00001437 static const char kPopupKey[] = "Popup";
Lei Zhanga21d5932018-02-05 18:28:38 +00001438 ASSERT_TRUE(FPDFAnnot_HasKey(annot.get(), kPopupKey));
1439 ASSERT_EQ(FPDF_OBJECT_REFERENCE,
1440 FPDFAnnot_GetValueType(annot.get(), kPopupKey));
Jane Liu300bb272017-08-21 14:37:53 -04001441
Lei Zhanga21d5932018-02-05 18:28:38 +00001442 // Retrieve and verify the popup of the highlight annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001443 ScopedFPDFAnnotation popup(
Lei Zhanga21d5932018-02-05 18:28:38 +00001444 FPDFAnnot_GetLinkedAnnot(annot.get(), kPopupKey));
1445 ASSERT_TRUE(popup);
1446 EXPECT_EQ(FPDF_ANNOT_POPUP, FPDFAnnot_GetSubtype(popup.get()));
1447 EXPECT_EQ(1, FPDFPage_GetAnnotIndex(page, popup.get()));
1448 FS_RECTF rect;
1449 ASSERT_TRUE(FPDFAnnot_GetRect(popup.get(), &rect));
1450 EXPECT_NEAR(612.0f, rect.left, 0.001f);
1451 EXPECT_NEAR(578.792, rect.bottom, 0.001f);
Jane Liu300bb272017-08-21 14:37:53 -04001452
Lei Zhanga21d5932018-02-05 18:28:38 +00001453 // Attempting to retrieve |annot|'s "IRT"-linked annotation would fail,
1454 // since "IRT" is not a key in |annot|'s dictionary.
Lei Zhang4f556b82019-04-08 16:32:41 +00001455 static const char kIRTKey[] = "IRT";
Lei Zhanga21d5932018-02-05 18:28:38 +00001456 ASSERT_FALSE(FPDFAnnot_HasKey(annot.get(), kIRTKey));
1457 EXPECT_FALSE(FPDFAnnot_GetLinkedAnnot(annot.get(), kIRTKey));
Jane Liu300bb272017-08-21 14:37:53 -04001458
Lei Zhanga21d5932018-02-05 18:28:38 +00001459 // Attempting to retrieve |annot|'s parent dictionary as an annotation
1460 // would fail, since its parent is not an annotation.
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001461 ASSERT_TRUE(FPDFAnnot_HasKey(annot.get(), pdfium::annotation::kP));
Lei Zhanga21d5932018-02-05 18:28:38 +00001462 EXPECT_EQ(FPDF_OBJECT_REFERENCE,
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001463 FPDFAnnot_GetValueType(annot.get(), pdfium::annotation::kP));
1464 EXPECT_FALSE(FPDFAnnot_GetLinkedAnnot(annot.get(), pdfium::annotation::kP));
Lei Zhanga21d5932018-02-05 18:28:38 +00001465 }
Jane Liu300bb272017-08-21 14:37:53 -04001466
Jane Liu300bb272017-08-21 14:37:53 -04001467 UnloadPage(page);
1468}
1469
Lei Zhangab41f252018-12-23 03:10:50 +00001470TEST_F(FPDFAnnotEmbedderTest, GetFormFieldFlagsTextField) {
Diana Gage7e0c05d2017-07-19 17:33:33 -07001471 // Open file with form text fields.
1472 ASSERT_TRUE(OpenDocument("text_form_multiple.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001473 FPDF_PAGE page = LoadPage(0);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001474 ASSERT_TRUE(page);
1475
Lei Zhanga21d5932018-02-05 18:28:38 +00001476 {
1477 // Retrieve the first annotation: user-editable text field.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001478 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001479 ASSERT_TRUE(annot);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001480
Lei Zhanga21d5932018-02-05 18:28:38 +00001481 // Check that the flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001482 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001483 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
Mansi Awasthi0b5da672020-01-23 18:17:18 +00001484 EXPECT_FALSE(flags & FPDF_FORMFLAG_TEXT_PASSWORD);
Lei Zhanga21d5932018-02-05 18:28:38 +00001485 }
Diana Gage7e0c05d2017-07-19 17:33:33 -07001486
Lei Zhanga21d5932018-02-05 18:28:38 +00001487 {
1488 // Retrieve the second annotation: read-only text field.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001489 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 1));
Lei Zhanga21d5932018-02-05 18:28:38 +00001490 ASSERT_TRUE(annot);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001491
Lei Zhanga21d5932018-02-05 18:28:38 +00001492 // Check that the flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001493 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001494 EXPECT_TRUE(flags & FPDF_FORMFLAG_READONLY);
Mansi Awasthi0b5da672020-01-23 18:17:18 +00001495 EXPECT_FALSE(flags & FPDF_FORMFLAG_TEXT_PASSWORD);
1496 }
1497
1498 {
1499 // Retrieve the fourth annotation: user-editable password text field.
1500 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 3));
1501 ASSERT_TRUE(annot);
1502
1503 // Check that the flag values are as expected.
1504 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
1505 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1506 EXPECT_TRUE(flags & FPDF_FORMFLAG_TEXT_PASSWORD);
Lei Zhanga21d5932018-02-05 18:28:38 +00001507 }
Diana Gage7e0c05d2017-07-19 17:33:33 -07001508
1509 UnloadPage(page);
1510}
1511
Lei Zhangab41f252018-12-23 03:10:50 +00001512TEST_F(FPDFAnnotEmbedderTest, GetFormFieldFlagsComboBox) {
Diana Gage7e0c05d2017-07-19 17:33:33 -07001513 // Open file with form text fields.
1514 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001515 FPDF_PAGE page = LoadPage(0);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001516 ASSERT_TRUE(page);
1517
Lei Zhanga21d5932018-02-05 18:28:38 +00001518 {
1519 // Retrieve the first annotation: user-editable combobox.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001520 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001521 ASSERT_TRUE(annot);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001522
Lei Zhanga21d5932018-02-05 18:28:38 +00001523 // Check that the flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001524 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001525 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1526 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1527 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1528 }
Diana Gage7e0c05d2017-07-19 17:33:33 -07001529
Lei Zhanga21d5932018-02-05 18:28:38 +00001530 {
1531 // Retrieve the second annotation: regular combobox.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001532 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 1));
Lei Zhanga21d5932018-02-05 18:28:38 +00001533 ASSERT_TRUE(annot);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001534
Lei Zhanga21d5932018-02-05 18:28:38 +00001535 // Check that the flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001536 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001537 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1538 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1539 EXPECT_FALSE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1540 }
Diana Gage7e0c05d2017-07-19 17:33:33 -07001541
Lei Zhanga21d5932018-02-05 18:28:38 +00001542 {
1543 // Retrieve the third annotation: read-only combobox.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001544 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +00001545 ASSERT_TRUE(annot);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001546
Lei Zhanga21d5932018-02-05 18:28:38 +00001547 // Check that the flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001548 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001549 EXPECT_TRUE(flags & FPDF_FORMFLAG_READONLY);
1550 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1551 EXPECT_FALSE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1552 }
Diana Gage7e0c05d2017-07-19 17:33:33 -07001553
1554 UnloadPage(page);
1555}
Diana Gage40870db2017-07-19 18:16:03 -07001556
Lei Zhangab41f252018-12-23 03:10:50 +00001557TEST_F(FPDFAnnotEmbedderTest, GetFormAnnotNull) {
Diana Gage40870db2017-07-19 18:16:03 -07001558 // Open file with form text fields.
1559 EXPECT_TRUE(OpenDocument("text_form.pdf"));
1560 FPDF_PAGE page = LoadPage(0);
1561 ASSERT_TRUE(page);
1562
1563 // Attempt to get an annotation where no annotation exists on page.
Lei Zhang8da98232019-12-11 23:29:33 +00001564 static const FS_POINTF kOriginPoint = {0.0f, 0.0f};
1565 EXPECT_FALSE(
1566 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, &kOriginPoint));
Lei Zhang7557e7b2018-09-14 17:02:40 +00001567
Lei Zhang8da98232019-12-11 23:29:33 +00001568 static const FS_POINTF kValidPoint = {120.0f, 120.0f};
Lei Zhang7557e7b2018-09-14 17:02:40 +00001569 {
1570 // Verify there is an annotation.
1571 ScopedFPDFAnnotation annot(
Lei Zhang8da98232019-12-11 23:29:33 +00001572 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, &kValidPoint));
Lei Zhang7557e7b2018-09-14 17:02:40 +00001573 EXPECT_TRUE(annot);
1574 }
1575
1576 // Try other bad inputs at a valid location.
Lei Zhang8da98232019-12-11 23:29:33 +00001577 EXPECT_FALSE(FPDFAnnot_GetFormFieldAtPoint(nullptr, nullptr, &kValidPoint));
1578 EXPECT_FALSE(FPDFAnnot_GetFormFieldAtPoint(nullptr, page, &kValidPoint));
1579 EXPECT_FALSE(
1580 FPDFAnnot_GetFormFieldAtPoint(form_handle(), nullptr, &kValidPoint));
Diana Gage40870db2017-07-19 18:16:03 -07001581
1582 UnloadPage(page);
1583}
1584
Lei Zhangab41f252018-12-23 03:10:50 +00001585TEST_F(FPDFAnnotEmbedderTest, GetFormAnnotAndCheckFlagsTextField) {
Diana Gage40870db2017-07-19 18:16:03 -07001586 // Open file with form text fields.
1587 EXPECT_TRUE(OpenDocument("text_form_multiple.pdf"));
1588 FPDF_PAGE page = LoadPage(0);
1589 ASSERT_TRUE(page);
1590
Lei Zhanga21d5932018-02-05 18:28:38 +00001591 {
1592 // Retrieve user-editable text field annotation.
Lei Zhang8da98232019-12-11 23:29:33 +00001593 static const FS_POINTF kPoint = {105.0f, 118.0f};
Tom Sepeze08d2b12018-04-25 18:49:32 +00001594 ScopedFPDFAnnotation annot(
Lei Zhang8da98232019-12-11 23:29:33 +00001595 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, &kPoint));
Lei Zhanga21d5932018-02-05 18:28:38 +00001596 ASSERT_TRUE(annot);
Diana Gage40870db2017-07-19 18:16:03 -07001597
Lei Zhanga21d5932018-02-05 18:28:38 +00001598 // Check that interactive form annotation flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001599 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001600 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1601 }
Diana Gage40870db2017-07-19 18:16:03 -07001602
Lei Zhanga21d5932018-02-05 18:28:38 +00001603 {
1604 // Retrieve read-only text field annotation.
Lei Zhang8da98232019-12-11 23:29:33 +00001605 static const FS_POINTF kPoint = {105.0f, 202.0f};
Tom Sepeze08d2b12018-04-25 18:49:32 +00001606 ScopedFPDFAnnotation annot(
Lei Zhang8da98232019-12-11 23:29:33 +00001607 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, &kPoint));
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_TRUE(flags & FPDF_FORMFLAG_READONLY);
1613 }
Diana Gage40870db2017-07-19 18:16:03 -07001614
1615 UnloadPage(page);
1616}
1617
Lei Zhangab41f252018-12-23 03:10:50 +00001618TEST_F(FPDFAnnotEmbedderTest, GetFormAnnotAndCheckFlagsComboBox) {
Diana Gage40870db2017-07-19 18:16:03 -07001619 // Open file with form comboboxes.
1620 EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
1621 FPDF_PAGE page = LoadPage(0);
1622 ASSERT_TRUE(page);
1623
Lei Zhanga21d5932018-02-05 18:28:38 +00001624 {
1625 // Retrieve user-editable combobox annotation.
Lei Zhang8da98232019-12-11 23:29:33 +00001626 static const FS_POINTF kPoint = {102.0f, 363.0f};
Tom Sepeze08d2b12018-04-25 18:49:32 +00001627 ScopedFPDFAnnotation annot(
Lei Zhang8da98232019-12-11 23:29:33 +00001628 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, &kPoint));
Lei Zhanga21d5932018-02-05 18:28:38 +00001629 ASSERT_TRUE(annot);
Diana Gage40870db2017-07-19 18:16:03 -07001630
Lei Zhanga21d5932018-02-05 18:28:38 +00001631 // Check that interactive form annotation flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001632 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001633 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1634 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1635 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1636 }
Diana Gage40870db2017-07-19 18:16:03 -07001637
Lei Zhanga21d5932018-02-05 18:28:38 +00001638 {
1639 // Retrieve regular combobox annotation.
Lei Zhang8da98232019-12-11 23:29:33 +00001640 static const FS_POINTF kPoint = {102.0f, 413.0f};
Tom Sepeze08d2b12018-04-25 18:49:32 +00001641 ScopedFPDFAnnotation annot(
Lei Zhang8da98232019-12-11 23:29:33 +00001642 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, &kPoint));
Lei Zhanga21d5932018-02-05 18:28:38 +00001643 ASSERT_TRUE(annot);
Diana Gage40870db2017-07-19 18:16:03 -07001644
Lei Zhanga21d5932018-02-05 18:28:38 +00001645 // Check that interactive form annotation flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001646 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001647 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1648 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1649 EXPECT_FALSE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1650 }
Diana Gage40870db2017-07-19 18:16:03 -07001651
Lei Zhanga21d5932018-02-05 18:28:38 +00001652 {
1653 // Retrieve read-only combobox annotation.
Lei Zhang8da98232019-12-11 23:29:33 +00001654 static const FS_POINTF kPoint = {102.0f, 513.0f};
Tom Sepeze08d2b12018-04-25 18:49:32 +00001655 ScopedFPDFAnnotation annot(
Lei Zhang8da98232019-12-11 23:29:33 +00001656 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, &kPoint));
Lei Zhanga21d5932018-02-05 18:28:38 +00001657 ASSERT_TRUE(annot);
Diana Gage40870db2017-07-19 18:16:03 -07001658
Lei Zhanga21d5932018-02-05 18:28:38 +00001659 // Check that interactive form annotation flag values are as expected.
Lei Zhanga9d33bd2019-07-31 05:37:31 +00001660 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001661 EXPECT_TRUE(flags & FPDF_FORMFLAG_READONLY);
1662 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1663 EXPECT_FALSE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1664 }
Diana Gage40870db2017-07-19 18:16:03 -07001665
1666 UnloadPage(page);
1667}
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001668
Lei Zhang03e5e682019-09-16 19:45:55 +00001669// TODO(crbug.com/pdfium/11): Fix this test and enable.
1670#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
1671#define MAYBE_BUG_1206 DISABLED_BUG_1206
1672#else
1673#define MAYBE_BUG_1206 BUG_1206
1674#endif
1675TEST_F(FPDFAnnotEmbedderTest, MAYBE_BUG_1206) {
Lei Zhang992e7e22019-02-04 19:20:58 +00001676 static constexpr size_t kExpectedSize = 1609;
1677 static const char kExpectedBitmap[] = "0d9fc05c6762fd788bd23fd87a4967bc";
1678
1679 ASSERT_TRUE(OpenDocument("bug_1206.pdf"));
1680
1681 FPDF_PAGE page = LoadPage(0);
1682 ASSERT_TRUE(page);
1683
1684 ASSERT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
1685 EXPECT_EQ(kExpectedSize, GetString().size());
1686 ClearString();
1687
1688 for (size_t i = 0; i < 10; ++i) {
1689 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
1690 CompareBitmap(bitmap.get(), 612, 792, kExpectedBitmap);
1691
1692 ASSERT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
1693 // TODO(https://crbug.com/pdfium/1206): This is wrong. The size should be
1694 // equal, not bigger.
1695 EXPECT_LT(kExpectedSize, GetString().size());
1696 ClearString();
1697 }
1698
1699 UnloadPage(page);
1700}
1701
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001702TEST_F(FPDFAnnotEmbedderTest, BUG_1212) {
1703 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
1704 FPDF_PAGE page = LoadPage(0);
1705 ASSERT_TRUE(page);
1706 EXPECT_EQ(0, FPDFPage_GetAnnotCount(page));
1707
1708 static const char kTestKey[] = "test";
Lei Zhang4f556b82019-04-08 16:32:41 +00001709 static const wchar_t kData[] = L"\xf6\xe4";
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001710 static const size_t kBufSize = 12;
1711 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(kBufSize);
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001712
1713 {
1714 // Add a text annotation to the page.
1715 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_TEXT));
1716 ASSERT_TRUE(annot);
1717 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
1718 EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
1719
1720 // Make sure there is no test key, add set a value there, and read it back.
1721 std::fill(buf.begin(), buf.end(), 'x');
1722 ASSERT_EQ(2u, FPDFAnnot_GetStringValue(annot.get(), kTestKey, buf.data(),
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001723 kBufSize));
1724 EXPECT_EQ(L"", GetPlatformWString(buf.data()));
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001725
Lei Zhangf0f67682019-04-08 17:03:21 +00001726 ScopedFPDFWideString text = GetFPDFWideString(kData);
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001727 EXPECT_TRUE(FPDFAnnot_SetStringValue(annot.get(), kTestKey, text.get()));
1728
1729 std::fill(buf.begin(), buf.end(), 'x');
1730 ASSERT_EQ(6u, FPDFAnnot_GetStringValue(annot.get(), kTestKey, buf.data(),
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001731 kBufSize));
1732 EXPECT_EQ(kData, GetPlatformWString(buf.data()));
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001733 }
1734
Lei Zhang05ec64c2019-01-09 03:00:06 +00001735 {
1736 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP));
1737 ASSERT_TRUE(annot);
Shikha Walia87ad4172019-11-08 20:55:19 +00001738 const FS_RECTF bounding_rect{206.0f, 753.0f, 339.0f, 709.0f};
Shikha Waliab54d7ad2019-11-06 02:06:33 +00001739 EXPECT_TRUE(FPDFAnnot_SetRect(annot.get(), &bounding_rect));
Lei Zhang05ec64c2019-01-09 03:00:06 +00001740 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
1741 EXPECT_EQ(FPDF_ANNOT_STAMP, FPDFAnnot_GetSubtype(annot.get()));
1742 // Also do the same test for its appearance string.
1743 std::fill(buf.begin(), buf.end(), 'x');
1744 ASSERT_EQ(2u,
1745 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001746 buf.data(), kBufSize));
1747 EXPECT_EQ(L"", GetPlatformWString(buf.data()));
Lei Zhang05ec64c2019-01-09 03:00:06 +00001748
Lei Zhangf0f67682019-04-08 17:03:21 +00001749 ScopedFPDFWideString text = GetFPDFWideString(kData);
Lei Zhang05ec64c2019-01-09 03:00:06 +00001750 EXPECT_TRUE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
1751 text.get()));
1752
1753 std::fill(buf.begin(), buf.end(), 'x');
1754 ASSERT_EQ(6u,
1755 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001756 buf.data(), kBufSize));
1757 EXPECT_EQ(kData, GetPlatformWString(buf.data()));
Lei Zhang05ec64c2019-01-09 03:00:06 +00001758 }
1759
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001760 UnloadPage(page);
1761
1762 {
1763 // Save a copy, open the copy, and check the annotation again.
1764 // Note that it renders the rotation.
1765 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang0b494052019-01-31 21:41:15 +00001766 ASSERT_TRUE(OpenSavedDocument());
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001767 FPDF_PAGE saved_page = LoadSavedPage(0);
1768 ASSERT_TRUE(saved_page);
1769
Lei Zhang05ec64c2019-01-09 03:00:06 +00001770 EXPECT_EQ(2, FPDFPage_GetAnnotCount(saved_page));
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001771 {
1772 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(saved_page, 0));
1773 ASSERT_TRUE(annot);
1774 EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
1775
1776 std::fill(buf.begin(), buf.end(), 'x');
1777 ASSERT_EQ(6u, FPDFAnnot_GetStringValue(annot.get(), kTestKey, buf.data(),
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001778 kBufSize));
1779 EXPECT_EQ(kData, GetPlatformWString(buf.data()));
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001780 }
1781
Lei Zhang05ec64c2019-01-09 03:00:06 +00001782 {
1783 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(saved_page, 0));
1784 ASSERT_TRUE(annot);
1785 // TODO(thestig): This return FPDF_ANNOT_UNKNOWN for some reason.
1786 // EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
1787
1788 std::fill(buf.begin(), buf.end(), 'x');
1789 ASSERT_EQ(6u, FPDFAnnot_GetStringValue(annot.get(), kTestKey, buf.data(),
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001790 kBufSize));
1791 EXPECT_EQ(kData, GetPlatformWString(buf.data()));
Lei Zhang05ec64c2019-01-09 03:00:06 +00001792 }
1793
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001794 CloseSavedPage(saved_page);
1795 CloseSavedDocument();
1796 }
1797}
rycsmithcb752f32019-02-21 18:40:53 +00001798
1799TEST_F(FPDFAnnotEmbedderTest, GetOptionCountCombobox) {
1800 // Open a file with combobox widget annotations and load its first page.
1801 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
1802 FPDF_PAGE page = LoadPage(0);
1803 ASSERT_TRUE(page);
1804
1805 {
1806 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1807 ASSERT_TRUE(annot);
1808
1809 EXPECT_EQ(3, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
1810
1811 annot.reset(FPDFPage_GetAnnot(page, 1));
1812 ASSERT_TRUE(annot);
1813
1814 EXPECT_EQ(26, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
Lei Zhange7033c82019-02-26 19:30:49 +00001815
1816 // Check bad form handle / annot.
1817 EXPECT_EQ(-1, FPDFAnnot_GetOptionCount(nullptr, nullptr));
1818 EXPECT_EQ(-1, FPDFAnnot_GetOptionCount(form_handle(), nullptr));
1819 EXPECT_EQ(-1, FPDFAnnot_GetOptionCount(nullptr, annot.get()));
rycsmithcb752f32019-02-21 18:40:53 +00001820 }
1821
1822 UnloadPage(page);
1823}
1824
1825TEST_F(FPDFAnnotEmbedderTest, GetOptionCountListbox) {
1826 // Open a file with listbox widget annotations and load its first page.
1827 ASSERT_TRUE(OpenDocument("listbox_form.pdf"));
1828 FPDF_PAGE page = LoadPage(0);
1829 ASSERT_TRUE(page);
1830
1831 {
1832 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1833 ASSERT_TRUE(annot);
1834
1835 EXPECT_EQ(3, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
1836
1837 annot.reset(FPDFPage_GetAnnot(page, 1));
1838 ASSERT_TRUE(annot);
1839
1840 EXPECT_EQ(26, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
1841 }
1842
1843 UnloadPage(page);
1844}
1845
1846TEST_F(FPDFAnnotEmbedderTest, GetOptionCountInvalidAnnotations) {
1847 // Open a file with ink annotations and load its first page.
1848 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
1849 FPDF_PAGE page = LoadPage(0);
1850 ASSERT_TRUE(page);
1851
1852 {
1853 // annotations do not have "Opt" array and will return -1
1854 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1855 ASSERT_TRUE(annot);
1856
1857 EXPECT_EQ(-1, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
1858
1859 annot.reset(FPDFPage_GetAnnot(page, 1));
1860 ASSERT_TRUE(annot);
1861
1862 EXPECT_EQ(-1, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
1863 }
1864
1865 UnloadPage(page);
1866}
1867
1868TEST_F(FPDFAnnotEmbedderTest, GetOptionLabelCombobox) {
1869 // Open a file with combobox widget annotations and load its first page.
1870 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
1871 FPDF_PAGE page = LoadPage(0);
1872 ASSERT_TRUE(page);
1873
1874 {
1875 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1876 ASSERT_TRUE(annot);
1877
1878 int index = 0;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001879 unsigned long length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001880 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001881 ASSERT_EQ(8u, length_bytes);
1882 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001883 EXPECT_EQ(8u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001884 buf.data(), length_bytes));
1885 EXPECT_EQ(L"Foo", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001886
1887 annot.reset(FPDFPage_GetAnnot(page, 1));
1888 ASSERT_TRUE(annot);
1889
1890 index = 0;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001891 length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001892 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001893 ASSERT_EQ(12u, length_bytes);
1894 buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001895 EXPECT_EQ(12u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001896 buf.data(), length_bytes));
1897 EXPECT_EQ(L"Apple", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001898
1899 index = 25;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001900 length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001901 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001902 buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001903 EXPECT_EQ(18u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001904 buf.data(), length_bytes));
1905 EXPECT_EQ(L"Zucchini", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001906
Lei Zhange7033c82019-02-26 19:30:49 +00001907 // Indices out of range
rycsmithcb752f32019-02-21 18:40:53 +00001908 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), -1,
1909 nullptr, 0));
1910 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), 26,
1911 nullptr, 0));
Lei Zhange7033c82019-02-26 19:30:49 +00001912
1913 // Check bad form handle / annot.
1914 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(nullptr, nullptr, 0, nullptr, 0));
1915 EXPECT_EQ(0u,
1916 FPDFAnnot_GetOptionLabel(nullptr, annot.get(), 0, nullptr, 0));
1917 EXPECT_EQ(0u,
1918 FPDFAnnot_GetOptionLabel(form_handle(), nullptr, 0, nullptr, 0));
rycsmithcb752f32019-02-21 18:40:53 +00001919 }
1920
1921 UnloadPage(page);
1922}
1923
1924TEST_F(FPDFAnnotEmbedderTest, GetOptionLabelListbox) {
1925 // Open a file with listbox widget annotations and load its first page.
1926 ASSERT_TRUE(OpenDocument("listbox_form.pdf"));
1927 FPDF_PAGE page = LoadPage(0);
1928 ASSERT_TRUE(page);
1929
1930 {
1931 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1932 ASSERT_TRUE(annot);
1933
1934 int index = 0;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001935 unsigned long length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001936 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001937 ASSERT_EQ(8u, length_bytes);
1938 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001939 EXPECT_EQ(8u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001940 buf.data(), length_bytes));
1941 EXPECT_EQ(L"Foo", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001942
1943 annot.reset(FPDFPage_GetAnnot(page, 1));
1944 ASSERT_TRUE(annot);
1945
1946 index = 0;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001947 length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001948 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001949 ASSERT_EQ(12u, length_bytes);
1950 buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001951 EXPECT_EQ(12u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001952 buf.data(), length_bytes));
1953 EXPECT_EQ(L"Apple", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001954
1955 index = 25;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001956 length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001957 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001958 ASSERT_EQ(18u, length_bytes);
1959 buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001960 EXPECT_EQ(18u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001961 buf.data(), length_bytes));
1962 EXPECT_EQ(L"Zucchini", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001963
1964 // indices out of range
1965 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), -1,
1966 nullptr, 0));
1967 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), 26,
1968 nullptr, 0));
1969 }
1970
1971 UnloadPage(page);
1972}
1973
1974TEST_F(FPDFAnnotEmbedderTest, GetOptionLabelInvalidAnnotations) {
1975 // Open a file with ink annotations and load its first page.
1976 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
1977 FPDF_PAGE page = LoadPage(0);
1978 ASSERT_TRUE(page);
1979
1980 {
1981 // annotations do not have "Opt" array and will return 0
1982 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1983 ASSERT_TRUE(annot);
1984
1985 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), 0,
1986 nullptr, 0));
1987
1988 annot.reset(FPDFPage_GetAnnot(page, 1));
1989 ASSERT_TRUE(annot);
1990
1991 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), 0,
1992 nullptr, 0));
1993 }
1994
1995 UnloadPage(page);
1996}
Ryan Smith09c23b12019-04-25 18:09:06 +00001997
1998TEST_F(FPDFAnnotEmbedderTest, GetFontSizeCombobox) {
1999 // Open a file with combobox annotations and load its first page.
2000 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
2001 FPDF_PAGE page = LoadPage(0);
2002 ASSERT_TRUE(page);
2003
2004 {
2005 // All 3 widgets have Tf font size 12.
2006 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2007 ASSERT_TRUE(annot);
2008
2009 float value;
2010 ASSERT_TRUE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value));
2011 EXPECT_EQ(12.0, value);
2012
2013 annot.reset(FPDFPage_GetAnnot(page, 1));
2014 ASSERT_TRUE(annot);
2015
2016 float value_two;
2017 ASSERT_TRUE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value_two));
2018 EXPECT_EQ(12.0, value_two);
2019
2020 annot.reset(FPDFPage_GetAnnot(page, 2));
2021 ASSERT_TRUE(annot);
2022
2023 float value_three;
2024 ASSERT_TRUE(
2025 FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value_three));
2026 EXPECT_EQ(12.0, value_three);
2027 }
2028
2029 UnloadPage(page);
2030}
2031
2032TEST_F(FPDFAnnotEmbedderTest, GetFontSizeTextField) {
2033 // Open a file with textfield annotations and load its first page.
2034 ASSERT_TRUE(OpenDocument("text_form_multiple.pdf"));
2035 FPDF_PAGE page = LoadPage(0);
2036 ASSERT_TRUE(page);
2037
2038 {
Mansi Awasthi0b5da672020-01-23 18:17:18 +00002039 // All 4 widgets have Tf font size 12.
Ryan Smith09c23b12019-04-25 18:09:06 +00002040 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2041 ASSERT_TRUE(annot);
2042
2043 float value;
2044 ASSERT_TRUE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value));
2045 EXPECT_EQ(12.0, value);
2046
2047 annot.reset(FPDFPage_GetAnnot(page, 1));
2048 ASSERT_TRUE(annot);
2049
2050 float value_two;
2051 ASSERT_TRUE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value_two));
2052 EXPECT_EQ(12.0, value_two);
2053
2054 annot.reset(FPDFPage_GetAnnot(page, 2));
2055 ASSERT_TRUE(annot);
2056
2057 float value_three;
2058 ASSERT_TRUE(
2059 FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value_three));
2060 EXPECT_EQ(12.0, value_three);
Mansi Awasthi0b5da672020-01-23 18:17:18 +00002061
2062 float value_four;
2063 ASSERT_TRUE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value_four));
2064 EXPECT_EQ(12.0, value_four);
Ryan Smith09c23b12019-04-25 18:09:06 +00002065 }
2066
2067 UnloadPage(page);
2068}
2069
2070TEST_F(FPDFAnnotEmbedderTest, GetFontSizeInvalidAnnotationTypes) {
2071 // Open a file with ink annotations and load its first page.
2072 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
2073 FPDF_PAGE page = LoadPage(0);
2074 ASSERT_TRUE(page);
2075
2076 {
2077 // Annotations that do not have variable text and will return -1.
2078 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2079 ASSERT_TRUE(annot);
2080
2081 float value;
2082 ASSERT_FALSE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value));
2083
2084 annot.reset(FPDFPage_GetAnnot(page, 1));
2085 ASSERT_TRUE(annot);
2086
2087 ASSERT_FALSE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value));
2088 }
2089
2090 UnloadPage(page);
2091}
2092
2093TEST_F(FPDFAnnotEmbedderTest, GetFontSizeInvalidArguments) {
2094 // Open a file with combobox annotations and load its first page.
2095 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
2096 FPDF_PAGE page = LoadPage(0);
2097 ASSERT_TRUE(page);
2098
2099 {
2100 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2101 ASSERT_TRUE(annot);
2102
2103 // Check bad form handle / annot.
2104 float value;
2105 ASSERT_FALSE(FPDFAnnot_GetFontSize(nullptr, annot.get(), &value));
2106 ASSERT_FALSE(FPDFAnnot_GetFontSize(form_handle(), nullptr, &value));
2107 ASSERT_FALSE(FPDFAnnot_GetFontSize(nullptr, nullptr, &value));
2108 }
2109
2110 UnloadPage(page);
2111}
2112
2113TEST_F(FPDFAnnotEmbedderTest, GetFontSizeNegative) {
2114 // Open a file with textfield annotations and load its first page.
2115 ASSERT_TRUE(OpenDocument("text_form_negative_fontsize.pdf"));
2116 FPDF_PAGE page = LoadPage(0);
2117 ASSERT_TRUE(page);
2118
2119 {
2120 // Obtain the first annotation, a text field with negative font size, -12.
2121 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2122 ASSERT_TRUE(annot);
2123
2124 float value;
2125 ASSERT_TRUE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value));
2126 EXPECT_EQ(-12.0, value);
2127 }
2128
2129 UnloadPage(page);
2130}
Ryan Smith23fdf892019-07-17 21:51:26 +00002131
2132TEST_F(FPDFAnnotEmbedderTest, IsCheckedCheckbox) {
2133 // Open a file with checkbox and radiobuttons widget annotations and load its
2134 // first page.
2135 ASSERT_TRUE(OpenDocument("click_form.pdf"));
2136 FPDF_PAGE page = LoadPage(0);
2137 ASSERT_TRUE(page);
2138
2139 {
2140 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 1));
2141 ASSERT_TRUE(annot);
2142 ASSERT_FALSE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2143 }
2144
2145 UnloadPage(page);
2146}
2147
2148TEST_F(FPDFAnnotEmbedderTest, IsCheckedCheckboxReadOnly) {
2149 // Open a file with checkbox and radiobutton widget annotations and load its
2150 // first page.
2151 ASSERT_TRUE(OpenDocument("click_form.pdf"));
2152 FPDF_PAGE page = LoadPage(0);
2153 ASSERT_TRUE(page);
2154
2155 {
2156 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2157 ASSERT_TRUE(annot);
2158 ASSERT_TRUE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2159 }
2160
2161 UnloadPage(page);
2162}
2163
2164TEST_F(FPDFAnnotEmbedderTest, IsCheckedRadioButton) {
2165 // Open a file with checkbox and radiobutton widget annotations and load its
2166 // first page.
2167 ASSERT_TRUE(OpenDocument("click_form.pdf"));
2168 FPDF_PAGE page = LoadPage(0);
2169 ASSERT_TRUE(page);
2170
2171 {
2172 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 5));
2173 ASSERT_TRUE(annot);
2174 ASSERT_FALSE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2175
2176 annot.reset(FPDFPage_GetAnnot(page, 6));
2177 ASSERT_FALSE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2178
2179 annot.reset(FPDFPage_GetAnnot(page, 7));
2180 ASSERT_TRUE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2181 }
2182
2183 UnloadPage(page);
2184}
2185
2186TEST_F(FPDFAnnotEmbedderTest, IsCheckedRadioButtonReadOnly) {
2187 // Open a file with checkbox and radiobutton widget annotations and load its
2188 // first page.
2189 ASSERT_TRUE(OpenDocument("click_form.pdf"));
2190 FPDF_PAGE page = LoadPage(0);
2191 ASSERT_TRUE(page);
2192
2193 {
2194 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
2195 ASSERT_TRUE(annot);
2196 ASSERT_FALSE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2197
2198 annot.reset(FPDFPage_GetAnnot(page, 3));
2199 ASSERT_FALSE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2200
2201 annot.reset(FPDFPage_GetAnnot(page, 4));
2202 ASSERT_TRUE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2203 }
2204
2205 UnloadPage(page);
2206}
2207
2208TEST_F(FPDFAnnotEmbedderTest, IsCheckedInvalidArguments) {
2209 // Open a file with checkbox and radiobuttons widget annotations and load its
2210 // first page.
2211 ASSERT_TRUE(OpenDocument("click_form.pdf"));
2212 FPDF_PAGE page = LoadPage(0);
2213 ASSERT_TRUE(page);
2214
2215 {
2216 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2217 ASSERT_TRUE(annot);
2218 ASSERT_FALSE(FPDFAnnot_IsChecked(nullptr, annot.get()));
2219 ASSERT_FALSE(FPDFAnnot_IsChecked(form_handle(), nullptr));
2220 ASSERT_FALSE(FPDFAnnot_IsChecked(nullptr, nullptr));
2221 }
2222
2223 UnloadPage(page);
2224}
2225
2226TEST_F(FPDFAnnotEmbedderTest, IsCheckedInvalidWidgetType) {
2227 // Open a file with text widget annotations and load its first page.
2228 ASSERT_TRUE(OpenDocument("text_form.pdf"));
2229 FPDF_PAGE page = LoadPage(0);
2230 ASSERT_TRUE(page);
2231
2232 {
2233 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2234 ASSERT_TRUE(annot);
2235 ASSERT_FALSE(FPDFAnnot_IsChecked(form_handle(), annot.get()));
2236 }
2237
2238 UnloadPage(page);
2239}
Mansi Awasthi07bf7e62020-01-24 10:34:17 +00002240
2241TEST_F(FPDFAnnotEmbedderTest, GetFormFieldTypeTextField) {
2242 ASSERT_TRUE(OpenDocument("text_form.pdf"));
2243 FPDF_PAGE page = LoadPage(0);
2244 ASSERT_TRUE(page);
2245
2246 {
2247 EXPECT_EQ(-1, FPDFAnnot_GetFormFieldType(form_handle(), nullptr));
2248
2249 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2250 ASSERT_TRUE(annot);
2251
2252 EXPECT_EQ(-1, FPDFAnnot_GetFormFieldType(nullptr, annot.get()));
2253
2254 EXPECT_EQ(FPDF_FORMFIELD_TEXTFIELD,
2255 FPDFAnnot_GetFormFieldType(form_handle(), annot.get()));
2256 }
2257 UnloadPage(page);
2258}
2259
2260TEST_F(FPDFAnnotEmbedderTest, GetFormFieldTypeComboBox) {
2261 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
2262 FPDF_PAGE page = LoadPage(0);
2263 ASSERT_TRUE(page);
2264
2265 {
2266 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2267 ASSERT_TRUE(annot);
2268 EXPECT_EQ(FPDF_FORMFIELD_COMBOBOX,
2269 FPDFAnnot_GetFormFieldType(form_handle(), annot.get()));
2270 }
2271 UnloadPage(page);
2272}
2273
2274TEST_F(FPDFAnnotEmbedderTest, GetFormFieldValueTextField) {
2275 ASSERT_TRUE(OpenDocument("text_form_multiple.pdf"));
2276 FPDF_PAGE page = LoadPage(0);
2277 ASSERT_TRUE(page);
2278
2279 {
2280 EXPECT_EQ(0u,
2281 FPDFAnnot_GetFormFieldValue(form_handle(), nullptr, nullptr, 0));
2282
2283 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2284 ASSERT_TRUE(annot);
2285
2286 EXPECT_EQ(0u,
2287 FPDFAnnot_GetFormFieldValue(nullptr, annot.get(), nullptr, 0));
2288
2289 unsigned long length_bytes =
2290 FPDFAnnot_GetFormFieldValue(form_handle(), annot.get(), nullptr, 0);
2291 ASSERT_EQ(2u, length_bytes);
2292 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
2293 EXPECT_EQ(2u, FPDFAnnot_GetFormFieldValue(form_handle(), annot.get(),
2294 buf.data(), length_bytes));
2295 EXPECT_EQ(L"", GetPlatformWString(buf.data()));
2296 }
2297 {
2298 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
2299 ASSERT_TRUE(annot);
2300
2301 unsigned long length_bytes =
2302 FPDFAnnot_GetFormFieldValue(form_handle(), annot.get(), nullptr, 0);
2303 ASSERT_EQ(18u, length_bytes);
2304 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
2305 EXPECT_EQ(18u, FPDFAnnot_GetFormFieldValue(form_handle(), annot.get(),
2306 buf.data(), length_bytes));
2307 EXPECT_EQ(L"Elephant", GetPlatformWString(buf.data()));
2308 }
2309 UnloadPage(page);
2310}
2311
2312TEST_F(FPDFAnnotEmbedderTest, GetFormFieldValueComboBox) {
2313 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
2314 FPDF_PAGE page = LoadPage(0);
2315 ASSERT_TRUE(page);
2316
2317 {
2318 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2319 ASSERT_TRUE(annot);
2320
2321 unsigned long length_bytes =
2322 FPDFAnnot_GetFormFieldValue(form_handle(), annot.get(), nullptr, 0);
2323 ASSERT_EQ(2u, length_bytes);
2324 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
2325 EXPECT_EQ(2u, FPDFAnnot_GetFormFieldValue(form_handle(), annot.get(),
2326 buf.data(), length_bytes));
2327 EXPECT_EQ(L"", GetPlatformWString(buf.data()));
2328 }
2329 {
2330 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 1));
2331 ASSERT_TRUE(annot);
2332
2333 unsigned long length_bytes =
2334 FPDFAnnot_GetFormFieldValue(form_handle(), annot.get(), nullptr, 0);
2335 ASSERT_EQ(14u, length_bytes);
2336 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
2337 EXPECT_EQ(14u, FPDFAnnot_GetFormFieldValue(form_handle(), annot.get(),
2338 buf.data(), length_bytes));
2339 EXPECT_EQ(L"Banana", GetPlatformWString(buf.data()));
2340 }
2341 UnloadPage(page);
2342}
2343
2344TEST_F(FPDFAnnotEmbedderTest, GetFormFieldNameTextField) {
2345 ASSERT_TRUE(OpenDocument("text_form.pdf"));
2346 FPDF_PAGE page = LoadPage(0);
2347 ASSERT_TRUE(page);
2348
2349 {
2350 EXPECT_EQ(0u,
2351 FPDFAnnot_GetFormFieldName(form_handle(), nullptr, nullptr, 0));
2352
2353 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2354 ASSERT_TRUE(annot);
2355
2356 EXPECT_EQ(0u, FPDFAnnot_GetFormFieldName(nullptr, annot.get(), nullptr, 0));
2357
2358 unsigned long length_bytes =
2359 FPDFAnnot_GetFormFieldName(form_handle(), annot.get(), nullptr, 0);
2360 ASSERT_EQ(18u, length_bytes);
2361 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
2362 EXPECT_EQ(18u, FPDFAnnot_GetFormFieldName(form_handle(), annot.get(),
2363 buf.data(), length_bytes));
2364 EXPECT_EQ(L"Text Box", GetPlatformWString(buf.data()));
2365 }
2366 UnloadPage(page);
2367}
2368
2369TEST_F(FPDFAnnotEmbedderTest, GetFormFieldNameComboBox) {
2370 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
2371 FPDF_PAGE page = LoadPage(0);
2372 ASSERT_TRUE(page);
2373
2374 {
2375 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2376 ASSERT_TRUE(annot);
2377
2378 unsigned long length_bytes =
2379 FPDFAnnot_GetFormFieldName(form_handle(), annot.get(), nullptr, 0);
2380 ASSERT_EQ(30u, length_bytes);
2381 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
2382 EXPECT_EQ(30u, FPDFAnnot_GetFormFieldName(form_handle(), annot.get(),
2383 buf.data(), length_bytes));
2384 EXPECT_EQ(L"Combo_Editable", GetPlatformWString(buf.data()));
2385 }
2386 UnloadPage(page);
2387}