blob: 7acef506f43c3a791f96fe3fa95372bc39c3f7b0 [file] [log] [blame]
Jane Liu4fd9a472017-06-01 18:56:09 -04001// Copyright 2017 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00005#include <algorithm>
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00006#include <cwchar>
Jane Liu20eafda2017-06-07 10:33:24 -04007#include <memory>
8#include <string>
Jane Liu4fd9a472017-06-01 18:56:09 -04009#include <vector>
10
Lei Zhange4cdac52019-04-30 16:45:57 +000011#include "build/build_config.h"
Lei Zhanga5c1daf2019-01-31 21:56:47 +000012#include "constants/annotation_common.h"
Jane Liubaa7ff42017-06-29 19:18:23 -040013#include "core/fxcrt/fx_system.h"
Tom Sepeze08d2b12018-04-25 18:49:32 +000014#include "public/cpp/fpdf_scopers.h"
Jane Liu4fd9a472017-06-01 18:56:09 -040015#include "public/fpdf_annot.h"
Jane Liubaa7ff42017-06-29 19:18:23 -040016#include "public/fpdf_edit.h"
Jane Liu4fd9a472017-06-01 18:56:09 -040017#include "public/fpdfview.h"
18#include "testing/embedder_test.h"
Lei Zhangb6992dd2019-02-05 23:30:20 +000019#include "testing/fx_string_testhelpers.h"
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +000020#include "testing/gmock/include/gmock/gmock-matchers.h"
Jane Liu4fd9a472017-06-01 18:56:09 -040021#include "testing/gtest/include/gtest/gtest.h"
Lei Zhang5bf8c7f2019-04-08 17:50:11 +000022#include "testing/utils/hash.h"
Jane Liu4fd9a472017-06-01 18:56:09 -040023
Lei Zhangab41f252018-12-23 03:10:50 +000024class FPDFAnnotEmbedderTest : public EmbedderTest {};
Jane Liu4fd9a472017-06-01 18:56:09 -040025
Lei Zhangab41f252018-12-23 03:10:50 +000026TEST_F(FPDFAnnotEmbedderTest, BadParams) {
Lei Zhang7557e7b2018-09-14 17:02:40 +000027 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
28 FPDF_PAGE page = LoadPage(0);
29 ASSERT_TRUE(page);
30
31 EXPECT_EQ(0, FPDFPage_GetAnnotCount(nullptr));
32
33 EXPECT_FALSE(FPDFPage_GetAnnot(nullptr, 0));
34 EXPECT_FALSE(FPDFPage_GetAnnot(nullptr, -1));
35 EXPECT_FALSE(FPDFPage_GetAnnot(nullptr, 1));
36 EXPECT_FALSE(FPDFPage_GetAnnot(page, -1));
37 EXPECT_FALSE(FPDFPage_GetAnnot(page, 1));
38
39 EXPECT_EQ(FPDF_ANNOT_UNKNOWN, FPDFAnnot_GetSubtype(nullptr));
40
41 EXPECT_EQ(0, FPDFAnnot_GetObjectCount(nullptr));
42
43 EXPECT_FALSE(FPDFAnnot_GetObject(nullptr, 0));
44 EXPECT_FALSE(FPDFAnnot_GetObject(nullptr, -1));
45 EXPECT_FALSE(FPDFAnnot_GetObject(nullptr, 1));
46
47 EXPECT_FALSE(FPDFAnnot_HasKey(nullptr, "foo"));
48
Lei Zhang4f556b82019-04-08 16:32:41 +000049 static const wchar_t kContents[] = L"Bar";
Lei Zhangf0f67682019-04-08 17:03:21 +000050 ScopedFPDFWideString text = GetFPDFWideString(kContents);
Lei Zhang7557e7b2018-09-14 17:02:40 +000051 EXPECT_FALSE(FPDFAnnot_SetStringValue(nullptr, "foo", text.get()));
52
Lei Zhang5bf8c7f2019-04-08 17:50:11 +000053 FPDF_WCHAR buffer[64];
Lei Zhang7557e7b2018-09-14 17:02:40 +000054 EXPECT_EQ(0u, FPDFAnnot_GetStringValue(nullptr, "foo", nullptr, 0));
55 EXPECT_EQ(0u, FPDFAnnot_GetStringValue(nullptr, "foo", buffer, 0));
56 EXPECT_EQ(0u,
57 FPDFAnnot_GetStringValue(nullptr, "foo", buffer, sizeof(buffer)));
58
59 UnloadPage(page);
60}
61
Lei Zhang3d9a0972019-03-04 19:34:09 +000062TEST_F(FPDFAnnotEmbedderTest, BadAnnotsEntry) {
63 ASSERT_TRUE(OpenDocument("bad_annots_entry.pdf"));
64 FPDF_PAGE page = LoadPage(0);
65 ASSERT_TRUE(page);
66
67 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
Lei Zhang98dc8c02019-03-04 19:40:30 +000068 EXPECT_FALSE(FPDFPage_GetAnnot(page, 0));
Lei Zhang3d9a0972019-03-04 19:34:09 +000069
70 UnloadPage(page);
71}
72
Lei Zhangab41f252018-12-23 03:10:50 +000073TEST_F(FPDFAnnotEmbedderTest, RenderAnnotWithOnlyRolloverAP) {
Jane Liue17011d2017-06-21 12:18:37 -040074 // Open a file with one annotation and load its first page.
75 ASSERT_TRUE(OpenDocument("annotation_highlight_rollover_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +000076 FPDF_PAGE page = LoadPage(0);
Jane Liue17011d2017-06-21 12:18:37 -040077 ASSERT_TRUE(page);
78
79 // This annotation has a malformed appearance stream, which does not have its
80 // normal appearance defined, only its rollover appearance. In this case, its
81 // normal appearance should be generated, allowing the highlight annotation to
82 // still display.
Tom Sepeze08d2b12018-04-25 18:49:32 +000083 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhanga98e3662018-02-07 20:28:35 +000084 CompareBitmap(bitmap.get(), 612, 792, "dc98f06da047bd8aabfa99562d2cbd1e");
Jane Liue17011d2017-06-21 12:18:37 -040085
86 UnloadPage(page);
87}
88
Lei Zhangab41f252018-12-23 03:10:50 +000089TEST_F(FPDFAnnotEmbedderTest, RenderMultilineMarkupAnnotWithoutAP) {
Lei Zhang4f556b82019-04-08 16:32:41 +000090 static const char kMd5[] = "76512832d88017668d9acc7aacd13dae";
Henrique Nakashima5098b252018-03-26 21:46:00 +000091 // Open a file with multiline markup annotations.
Ralf Sipplb3a52402018-03-19 23:30:28 +000092 ASSERT_TRUE(OpenDocument("annotation_markup_multiline_no_ap.pdf"));
93 FPDF_PAGE page = LoadPage(0);
94 ASSERT_TRUE(page);
95
Tom Sepeze08d2b12018-04-25 18:49:32 +000096 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +000097 CompareBitmap(bitmap.get(), 595, 842, kMd5);
Ralf Sipplb3a52402018-03-19 23:30:28 +000098
99 UnloadPage(page);
100}
101
Lei Zhangab41f252018-12-23 03:10:50 +0000102TEST_F(FPDFAnnotEmbedderTest, ExtractHighlightLongContent) {
Jane Liu4fd9a472017-06-01 18:56:09 -0400103 // Open a file with one annotation and load its first page.
104 ASSERT_TRUE(OpenDocument("annotation_highlight_long_content.pdf"));
Tom Sepez507d0192018-11-07 16:37:51 +0000105 FPDF_PAGE page = LoadPageNoEvents(0);
Jane Liu4fd9a472017-06-01 18:56:09 -0400106 ASSERT_TRUE(page);
107
108 // Check that there is a total of 1 annotation on its first page.
109 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
110
111 // Check that the annotation is of type "highlight".
Lei Zhanga21d5932018-02-05 18:28:38 +0000112 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000113 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000114 ASSERT_TRUE(annot);
115 EXPECT_EQ(FPDF_ANNOT_HIGHLIGHT, FPDFAnnot_GetSubtype(annot.get()));
Jane Liu4fd9a472017-06-01 18:56:09 -0400116
Lei Zhanga21d5932018-02-05 18:28:38 +0000117 // Check that the annotation color is yellow.
118 unsigned int R;
119 unsigned int G;
120 unsigned int B;
121 unsigned int A;
Lei Zhang75c81712018-02-08 17:22:39 +0000122 ASSERT_TRUE(FPDFAnnot_GetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, &R,
Lei Zhanga21d5932018-02-05 18:28:38 +0000123 &G, &B, &A));
124 EXPECT_EQ(255u, R);
125 EXPECT_EQ(255u, G);
126 EXPECT_EQ(0u, B);
127 EXPECT_EQ(255u, A);
Jane Liu4fd9a472017-06-01 18:56:09 -0400128
Lei Zhanga21d5932018-02-05 18:28:38 +0000129 // Check that the author is correct.
Lei Zhang4f556b82019-04-08 16:32:41 +0000130 static const char kAuthorKey[] = "T";
Lei Zhanga21d5932018-02-05 18:28:38 +0000131 EXPECT_EQ(FPDF_OBJECT_STRING,
132 FPDFAnnot_GetValueType(annot.get(), kAuthorKey));
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000133 unsigned long length_bytes =
Lei Zhanga21d5932018-02-05 18:28:38 +0000134 FPDFAnnot_GetStringValue(annot.get(), kAuthorKey, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000135 ASSERT_EQ(28u, length_bytes);
136 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
Lei Zhanga21d5932018-02-05 18:28:38 +0000137 EXPECT_EQ(28u, FPDFAnnot_GetStringValue(annot.get(), kAuthorKey, buf.data(),
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000138 length_bytes));
139 EXPECT_EQ(L"Jae Hyun Park", GetPlatformWString(buf.data()));
Jane Liu4fd9a472017-06-01 18:56:09 -0400140
Lei Zhanga21d5932018-02-05 18:28:38 +0000141 // Check that the content is correct.
Lei Zhanga5c1daf2019-01-31 21:56:47 +0000142 EXPECT_EQ(
143 FPDF_OBJECT_STRING,
144 FPDFAnnot_GetValueType(annot.get(), pdfium::annotation::kContents));
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000145 length_bytes = FPDFAnnot_GetStringValue(
146 annot.get(), pdfium::annotation::kContents, nullptr, 0);
147 ASSERT_EQ(2690u, length_bytes);
148 buf = GetFPDFWideStringBuffer(length_bytes);
149 EXPECT_EQ(2690u, FPDFAnnot_GetStringValue(annot.get(),
150 pdfium::annotation::kContents,
151 buf.data(), length_bytes));
Lei Zhang4f556b82019-04-08 16:32:41 +0000152 static const wchar_t kContents[] =
Lei Zhanga21d5932018-02-05 18:28:38 +0000153 L"This is a note for that highlight annotation. Very long highlight "
154 "annotation. Long long long Long long longLong long longLong long "
155 "longLong long longLong long longLong long longLong long longLong long "
156 "longLong long longLong long longLong long longLong long longLong long "
157 "longLong long longLong long longLong long longLong long longLong long "
158 "longLong long longLong long longLong long longLong long longLong long "
159 "longLong long longLong long longLong long longLong long longLong long "
160 "longLong long longLong long longLong long longLong long longLong long "
161 "longLong long longLong long longLong long longLong long longLong long "
162 "longLong long longLong long longLong long longLong long longLong long "
163 "longLong long longLong long longLong long longLong long longLong long "
164 "longLong long longLong long longLong long longLong long longLong long "
165 "longLong long longLong long longLong long longLong long longLong long "
166 "longLong long longLong long longLong long longLong long longLong long "
167 "longLong long longLong long longLong long longLong long longLong long "
168 "longLong long longLong long longLong long longLong long longLong long "
169 "longLong long longLong long longLong long longLong long longLong long "
170 "longLong long longLong long longLong long longLong long longLong long "
171 "longLong long longLong long longLong long longLong long longLong long "
172 "longLong long long. END";
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000173 EXPECT_EQ(kContents, GetPlatformWString(buf.data()));
Jane Liu4fd9a472017-06-01 18:56:09 -0400174
Lei Zhanga21d5932018-02-05 18:28:38 +0000175 // Check that the quadpoints are correct.
176 FS_QUADPOINTSF quadpoints;
Ralf Sippl16381792018-04-12 21:20:26 +0000177 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot.get(), 0, &quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000178 EXPECT_EQ(115.802643f, quadpoints.x1);
179 EXPECT_EQ(718.913940f, quadpoints.y1);
180 EXPECT_EQ(157.211182f, quadpoints.x4);
181 EXPECT_EQ(706.264465f, quadpoints.y4);
182 }
Tom Sepez507d0192018-11-07 16:37:51 +0000183 UnloadPageNoEvents(page);
Jane Liu4fd9a472017-06-01 18:56:09 -0400184}
185
Lei Zhangab41f252018-12-23 03:10:50 +0000186TEST_F(FPDFAnnotEmbedderTest, ExtractInkMultiple) {
Jane Liu4fd9a472017-06-01 18:56:09 -0400187 // Open a file with three annotations and load its first page.
188 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
Tom Sepez507d0192018-11-07 16:37:51 +0000189 FPDF_PAGE page = LoadPageNoEvents(0);
Jane Liu4fd9a472017-06-01 18:56:09 -0400190 ASSERT_TRUE(page);
191
192 // Check that there is a total of 3 annotation on its first page.
193 EXPECT_EQ(3, FPDFPage_GetAnnotCount(page));
194
Lei Zhanga21d5932018-02-05 18:28:38 +0000195 {
196 // Check that the third annotation is of type "ink".
Tom Sepeze08d2b12018-04-25 18:49:32 +0000197 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +0000198 ASSERT_TRUE(annot);
199 EXPECT_EQ(FPDF_ANNOT_INK, FPDFAnnot_GetSubtype(annot.get()));
Jane Liu4fd9a472017-06-01 18:56:09 -0400200
Lei Zhanga21d5932018-02-05 18:28:38 +0000201 // Check that the annotation color is blue with opacity.
202 unsigned int R;
203 unsigned int G;
204 unsigned int B;
205 unsigned int A;
Lei Zhang75c81712018-02-08 17:22:39 +0000206 ASSERT_TRUE(FPDFAnnot_GetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, &R,
Lei Zhanga21d5932018-02-05 18:28:38 +0000207 &G, &B, &A));
208 EXPECT_EQ(0u, R);
209 EXPECT_EQ(0u, G);
210 EXPECT_EQ(255u, B);
211 EXPECT_EQ(76u, A);
Jane Liu4fd9a472017-06-01 18:56:09 -0400212
Lei Zhanga21d5932018-02-05 18:28:38 +0000213 // Check that there is no content.
Lei Zhanga5c1daf2019-01-31 21:56:47 +0000214 EXPECT_EQ(2u, FPDFAnnot_GetStringValue(
215 annot.get(), pdfium::annotation::kContents, nullptr, 0));
Jane Liu4fd9a472017-06-01 18:56:09 -0400216
Lei Zhang4f556b82019-04-08 16:32:41 +0000217 // Check that the rectangle coordinates are correct.
Lei Zhanga21d5932018-02-05 18:28:38 +0000218 // Note that upon rendering, the rectangle coordinates will be adjusted.
219 FS_RECTF rect;
220 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
221 EXPECT_EQ(351.820404f, rect.left);
222 EXPECT_EQ(583.830688f, rect.bottom);
223 EXPECT_EQ(475.336090f, rect.right);
224 EXPECT_EQ(681.535034f, rect.top);
225 }
Tom Sepezef43c262018-11-07 16:41:32 +0000226 {
227 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
228 CompareBitmap(bitmap.get(), 612, 792, "354002e1c4386d38fdde29ef8d61074a");
229 }
Tom Sepez507d0192018-11-07 16:37:51 +0000230 UnloadPageNoEvents(page);
Jane Liu4fd9a472017-06-01 18:56:09 -0400231}
Jane Liu20eafda2017-06-07 10:33:24 -0400232
Lei Zhangab41f252018-12-23 03:10:50 +0000233TEST_F(FPDFAnnotEmbedderTest, AddIllegalSubtypeAnnotation) {
Jane Liu20eafda2017-06-07 10:33:24 -0400234 // Open a file with one annotation and load its first page.
235 ASSERT_TRUE(OpenDocument("annotation_highlight_long_content.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000236 FPDF_PAGE page = LoadPage(0);
Jane Liu20eafda2017-06-07 10:33:24 -0400237 ASSERT_TRUE(page);
238
239 // Add an annotation with an illegal subtype.
Jane Liud60e9ad2017-06-26 11:28:36 -0400240 ASSERT_FALSE(FPDFPage_CreateAnnot(page, -1));
Jane Liu20eafda2017-06-07 10:33:24 -0400241
242 UnloadPage(page);
243}
244
Lei Zhangab41f252018-12-23 03:10:50 +0000245TEST_F(FPDFAnnotEmbedderTest, AddFirstTextAnnotation) {
Jane Liu20eafda2017-06-07 10:33:24 -0400246 // Open a file with no annotation and load its first page.
247 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000248 FPDF_PAGE page = LoadPage(0);
Jane Liu20eafda2017-06-07 10:33:24 -0400249 ASSERT_TRUE(page);
250 EXPECT_EQ(0, FPDFPage_GetAnnotCount(page));
251
Lei Zhanga21d5932018-02-05 18:28:38 +0000252 {
253 // Add a text annotation to the page.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000254 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_TEXT));
Lei Zhanga21d5932018-02-05 18:28:38 +0000255 ASSERT_TRUE(annot);
Jane Liu20eafda2017-06-07 10:33:24 -0400256
Lei Zhanga21d5932018-02-05 18:28:38 +0000257 // Check that there is now 1 annotations on this page.
258 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
Jane Liu20eafda2017-06-07 10:33:24 -0400259
Lei Zhanga21d5932018-02-05 18:28:38 +0000260 // Check that the subtype of the annotation is correct.
261 EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
262 }
Jane Liue10509a2017-06-20 16:47:41 -0400263
Lei Zhanga21d5932018-02-05 18:28:38 +0000264 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000265 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000266 ASSERT_TRUE(annot);
267 EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
Jane Liu20eafda2017-06-07 10:33:24 -0400268
Lei Zhanga21d5932018-02-05 18:28:38 +0000269 // Set the color of the annotation.
270 ASSERT_TRUE(FPDFAnnot_SetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, 51,
271 102, 153, 204));
272 // Check that the color has been set correctly.
273 unsigned int R;
274 unsigned int G;
275 unsigned int B;
276 unsigned int A;
Lei Zhang75c81712018-02-08 17:22:39 +0000277 ASSERT_TRUE(FPDFAnnot_GetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, &R,
Lei Zhanga21d5932018-02-05 18:28:38 +0000278 &G, &B, &A));
279 EXPECT_EQ(51u, R);
280 EXPECT_EQ(102u, G);
281 EXPECT_EQ(153u, B);
282 EXPECT_EQ(204u, A);
Jane Liu20eafda2017-06-07 10:33:24 -0400283
Lei Zhanga21d5932018-02-05 18:28:38 +0000284 // Change the color of the annotation.
285 ASSERT_TRUE(FPDFAnnot_SetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, 204,
286 153, 102, 51));
287 // Check that the color has been set correctly.
Lei Zhang75c81712018-02-08 17:22:39 +0000288 ASSERT_TRUE(FPDFAnnot_GetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, &R,
Lei Zhanga21d5932018-02-05 18:28:38 +0000289 &G, &B, &A));
290 EXPECT_EQ(204u, R);
291 EXPECT_EQ(153u, G);
292 EXPECT_EQ(102u, B);
293 EXPECT_EQ(51u, A);
Jane Liu20eafda2017-06-07 10:33:24 -0400294
Lei Zhanga21d5932018-02-05 18:28:38 +0000295 // Set the annotation rectangle.
296 FS_RECTF rect;
297 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
298 EXPECT_EQ(0.f, rect.left);
299 EXPECT_EQ(0.f, rect.right);
300 rect.left = 35;
301 rect.bottom = 150;
302 rect.right = 53;
303 rect.top = 165;
304 ASSERT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
305 // Check that the annotation rectangle has been set correctly.
306 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
307 EXPECT_EQ(35.f, rect.left);
308 EXPECT_EQ(150.f, rect.bottom);
309 EXPECT_EQ(53.f, rect.right);
310 EXPECT_EQ(165.f, rect.top);
Jane Liu20eafda2017-06-07 10:33:24 -0400311
Lei Zhanga21d5932018-02-05 18:28:38 +0000312 // Set the content of the annotation.
Lei Zhang4f556b82019-04-08 16:32:41 +0000313 static const wchar_t kContents[] = L"Hello! This is a customized content.";
Lei Zhangf0f67682019-04-08 17:03:21 +0000314 ScopedFPDFWideString text = GetFPDFWideString(kContents);
Lei Zhanga5c1daf2019-01-31 21:56:47 +0000315 ASSERT_TRUE(FPDFAnnot_SetStringValue(
316 annot.get(), pdfium::annotation::kContents, text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +0000317 // Check that the content has been set correctly.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000318 unsigned long length_bytes = FPDFAnnot_GetStringValue(
Lei Zhanga5c1daf2019-01-31 21:56:47 +0000319 annot.get(), pdfium::annotation::kContents, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +0000320 ASSERT_EQ(74u, length_bytes);
321 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
322 EXPECT_EQ(74u, FPDFAnnot_GetStringValue(annot.get(),
323 pdfium::annotation::kContents,
324 buf.data(), length_bytes));
325 EXPECT_EQ(kContents, GetPlatformWString(buf.data()));
Lei Zhanga21d5932018-02-05 18:28:38 +0000326 }
Jane Liu20eafda2017-06-07 10:33:24 -0400327 UnloadPage(page);
328}
329
Lei Zhangab41f252018-12-23 03:10:50 +0000330TEST_F(FPDFAnnotEmbedderTest, AddAndSaveUnderlineAnnotation) {
Jane Liu20eafda2017-06-07 10:33:24 -0400331 // Open a file with one annotation and load its first page.
332 ASSERT_TRUE(OpenDocument("annotation_highlight_long_content.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000333 FPDF_PAGE page = LoadPage(0);
Jane Liu20eafda2017-06-07 10:33:24 -0400334 ASSERT_TRUE(page);
335
336 // Check that there is a total of one annotation on its first page, and verify
337 // its quadpoints.
338 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
Jane Liu0c6b07d2017-08-15 10:50:22 -0400339 FS_QUADPOINTSF quadpoints;
Lei Zhanga21d5932018-02-05 18:28:38 +0000340 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000341 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000342 ASSERT_TRUE(annot);
Ralf Sippl16381792018-04-12 21:20:26 +0000343 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot.get(), 0, &quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000344 EXPECT_EQ(115.802643f, quadpoints.x1);
345 EXPECT_EQ(718.913940f, quadpoints.y1);
346 EXPECT_EQ(157.211182f, quadpoints.x4);
347 EXPECT_EQ(706.264465f, quadpoints.y4);
348 }
Jane Liu20eafda2017-06-07 10:33:24 -0400349
350 // Add an underline annotation to the page and set its quadpoints.
Lei Zhanga21d5932018-02-05 18:28:38 +0000351 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000352 ScopedFPDFAnnotation annot(
Lei Zhanga21d5932018-02-05 18:28:38 +0000353 FPDFPage_CreateAnnot(page, FPDF_ANNOT_UNDERLINE));
354 ASSERT_TRUE(annot);
355 quadpoints.x1 = 140.802643f;
356 quadpoints.x3 = 140.802643f;
Ralf Sippl16381792018-04-12 21:20:26 +0000357 ASSERT_TRUE(FPDFAnnot_AppendAttachmentPoints(annot.get(), &quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000358 }
Jane Liu20eafda2017-06-07 10:33:24 -0400359
360 // Save the document, closing the page and document.
361 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang75c81712018-02-08 17:22:39 +0000362 UnloadPage(page);
Jane Liu20eafda2017-06-07 10:33:24 -0400363
364 // Open the saved document.
Lei Zhang4f556b82019-04-08 16:32:41 +0000365 static const char kMd5[] = "dba153419f67b7c0c0e3d22d3e8910d5";
Dan Sinclair04e4dc82017-10-18 12:17:14 -0400366
Lei Zhang0b494052019-01-31 21:41:15 +0000367 ASSERT_TRUE(OpenSavedDocument());
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000368 page = LoadSavedPage(0);
Lei Zhang4f556b82019-04-08 16:32:41 +0000369 VerifySavedRendering(page, 612, 792, kMd5);
Jane Liu20eafda2017-06-07 10:33:24 -0400370
371 // Check that the saved document has 2 annotations on the first page
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000372 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
Jane Liu20eafda2017-06-07 10:33:24 -0400373
Lei Zhanga21d5932018-02-05 18:28:38 +0000374 {
375 // Check that the second annotation is an underline annotation and verify
376 // its quadpoints.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000377 ScopedFPDFAnnotation new_annot(FPDFPage_GetAnnot(page, 1));
Lei Zhanga21d5932018-02-05 18:28:38 +0000378 ASSERT_TRUE(new_annot);
379 EXPECT_EQ(FPDF_ANNOT_UNDERLINE, FPDFAnnot_GetSubtype(new_annot.get()));
380 FS_QUADPOINTSF new_quadpoints;
381 ASSERT_TRUE(
Ralf Sippl16381792018-04-12 21:20:26 +0000382 FPDFAnnot_GetAttachmentPoints(new_annot.get(), 0, &new_quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000383 EXPECT_NEAR(quadpoints.x1, new_quadpoints.x1, 0.001f);
384 EXPECT_NEAR(quadpoints.y1, new_quadpoints.y1, 0.001f);
385 EXPECT_NEAR(quadpoints.x4, new_quadpoints.x4, 0.001f);
386 EXPECT_NEAR(quadpoints.y4, new_quadpoints.y4, 0.001f);
387 }
Dan Sinclair04e4dc82017-10-18 12:17:14 -0400388
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000389 CloseSavedPage(page);
Dan Sinclair04e4dc82017-10-18 12:17:14 -0400390 CloseSavedDocument();
Jane Liu20eafda2017-06-07 10:33:24 -0400391}
Jane Liu06462752017-06-27 16:41:14 -0400392
Lei Zhangab41f252018-12-23 03:10:50 +0000393TEST_F(FPDFAnnotEmbedderTest, GetAndSetQuadPoints) {
Ralf Sippl16381792018-04-12 21:20:26 +0000394 // Open a file with four annotations and load its first page.
395 ASSERT_TRUE(OpenDocument("annotation_highlight_square_with_ap.pdf"));
396 FPDF_PAGE page = LoadPage(0);
397 ASSERT_TRUE(page);
398 EXPECT_EQ(4, FPDFPage_GetAnnotCount(page));
399
400 // Retrieve the highlight annotation.
401 FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 0);
402 ASSERT_TRUE(annot);
403 ASSERT_EQ(FPDF_ANNOT_HIGHLIGHT, FPDFAnnot_GetSubtype(annot));
404
405 FS_QUADPOINTSF quadpoints;
406 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot, 0, &quadpoints));
407
408 {
409 // Verify the current one set of quadpoints.
410 ASSERT_EQ(1u, FPDFAnnot_CountAttachmentPoints(annot));
411
412 EXPECT_NEAR(72.0000f, quadpoints.x1, 0.001f);
413 EXPECT_NEAR(720.792f, quadpoints.y1, 0.001f);
414 EXPECT_NEAR(132.055f, quadpoints.x4, 0.001f);
415 EXPECT_NEAR(704.796f, quadpoints.y4, 0.001f);
416 }
417
418 {
419 // Update the quadpoints.
420 FS_QUADPOINTSF new_quadpoints = quadpoints;
421 new_quadpoints.y1 -= 20.f;
422 new_quadpoints.y2 -= 20.f;
423 new_quadpoints.y3 -= 20.f;
424 new_quadpoints.y4 -= 20.f;
425 ASSERT_TRUE(FPDFAnnot_SetAttachmentPoints(annot, 0, &new_quadpoints));
426
427 // Verify added quadpoint set
428 ASSERT_EQ(1u, FPDFAnnot_CountAttachmentPoints(annot));
429 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot, 0, &quadpoints));
430 EXPECT_NEAR(new_quadpoints.x1, quadpoints.x1, 0.001f);
431 EXPECT_NEAR(new_quadpoints.y1, quadpoints.y1, 0.001f);
432 EXPECT_NEAR(new_quadpoints.x4, quadpoints.x4, 0.001f);
433 EXPECT_NEAR(new_quadpoints.y4, quadpoints.y4, 0.001f);
434 }
435
436 {
437 // Append a new set of quadpoints.
438 FS_QUADPOINTSF new_quadpoints = quadpoints;
439 new_quadpoints.y1 += 20.f;
440 new_quadpoints.y2 += 20.f;
441 new_quadpoints.y3 += 20.f;
442 new_quadpoints.y4 += 20.f;
443 ASSERT_TRUE(FPDFAnnot_AppendAttachmentPoints(annot, &new_quadpoints));
444
445 // Verify added quadpoint set
446 ASSERT_EQ(2u, FPDFAnnot_CountAttachmentPoints(annot));
447 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot, 1, &quadpoints));
448 EXPECT_NEAR(new_quadpoints.x1, quadpoints.x1, 0.001f);
449 EXPECT_NEAR(new_quadpoints.y1, quadpoints.y1, 0.001f);
450 EXPECT_NEAR(new_quadpoints.x4, quadpoints.x4, 0.001f);
451 EXPECT_NEAR(new_quadpoints.y4, quadpoints.y4, 0.001f);
452 }
453
454 {
455 // Setting and getting quadpoints at out-of-bound index should fail
456 EXPECT_FALSE(FPDFAnnot_SetAttachmentPoints(annot, 300000, &quadpoints));
457 EXPECT_FALSE(FPDFAnnot_GetAttachmentPoints(annot, 300000, &quadpoints));
458 }
459
460 FPDFPage_CloseAnnot(annot);
461
462 // Retrieve the square annotation
463 FPDF_ANNOTATION squareAnnot = FPDFPage_GetAnnot(page, 2);
464
465 {
466 // Check that attempting to set its quadpoints would fail
467 ASSERT_TRUE(squareAnnot);
468 EXPECT_EQ(FPDF_ANNOT_SQUARE, FPDFAnnot_GetSubtype(squareAnnot));
469 EXPECT_EQ(0u, FPDFAnnot_CountAttachmentPoints(squareAnnot));
470 EXPECT_FALSE(FPDFAnnot_SetAttachmentPoints(squareAnnot, 0, &quadpoints));
471 }
472
473 FPDFPage_CloseAnnot(squareAnnot);
Ralf Sippl16381792018-04-12 21:20:26 +0000474 UnloadPage(page);
475}
476
Lei Zhangab41f252018-12-23 03:10:50 +0000477TEST_F(FPDFAnnotEmbedderTest, ModifyRectQuadpointsWithAP) {
Lei Zhange4cdac52019-04-30 16:45:57 +0000478#if defined(OS_MACOSX)
Lei Zhang4f556b82019-04-08 16:32:41 +0000479 static const char kMd5Original[] = "63af8432fab95a67cdebb7cd0e514941";
480 static const char kMd5ModifiedHighlight[] =
481 "aec26075011349dec9bace891856b5f2";
482 static const char kMd5ModifiedSquare[] = "057f57a32be95975775e5ec513fdcb56";
Dan Sinclair698aed72017-09-26 16:24:49 -0400483#elif _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
Lei Zhang4f556b82019-04-08 16:32:41 +0000484 static const char kMd5Original[] = "0e27376094f11490f74c65f3dc3a42c5";
485 static const char kMd5ModifiedHighlight[] =
486 "66f3caef3a7d488a4fa1ad37fc06310e";
487 static const char kMd5ModifiedSquare[] = "a456dad0bc6801ee2d6408a4394af563";
Jane Liub370e5a2017-08-16 13:24:58 -0400488#else
Lei Zhang4f556b82019-04-08 16:32:41 +0000489 static const char kMd5Original[] = "0e27376094f11490f74c65f3dc3a42c5";
490 static const char kMd5ModifiedHighlight[] =
491 "66f3caef3a7d488a4fa1ad37fc06310e";
492 static const char kMd5ModifiedSquare[] = "a456dad0bc6801ee2d6408a4394af563";
Jane Liub370e5a2017-08-16 13:24:58 -0400493#endif
494
Jane Liu06462752017-06-27 16:41:14 -0400495 // Open a file with four annotations and load its first page.
496 ASSERT_TRUE(OpenDocument("annotation_highlight_square_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000497 FPDF_PAGE page = LoadPage(0);
Jane Liu06462752017-06-27 16:41:14 -0400498 ASSERT_TRUE(page);
499 EXPECT_EQ(4, FPDFPage_GetAnnotCount(page));
500
Jane Liub370e5a2017-08-16 13:24:58 -0400501 // Check that the original file renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000502 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000503 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000504 CompareBitmap(bitmap.get(), 612, 792, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000505 }
Jane Liub370e5a2017-08-16 13:24:58 -0400506
Jane Liu0c6b07d2017-08-15 10:50:22 -0400507 FS_RECTF rect;
Jane Liu0c6b07d2017-08-15 10:50:22 -0400508 FS_RECTF new_rect;
Lei Zhanga21d5932018-02-05 18:28:38 +0000509
510 // Retrieve the highlight annotation which has its AP stream already defined.
511 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000512 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000513 ASSERT_TRUE(annot);
514 EXPECT_EQ(FPDF_ANNOT_HIGHLIGHT, FPDFAnnot_GetSubtype(annot.get()));
515
516 // Check that color cannot be set when an AP stream is defined already.
517 EXPECT_FALSE(FPDFAnnot_SetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, 51,
518 102, 153, 204));
519
520 // Verify its attachment points.
521 FS_QUADPOINTSF quadpoints;
Ralf Sippl16381792018-04-12 21:20:26 +0000522 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot.get(), 0, &quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000523 EXPECT_NEAR(72.0000f, quadpoints.x1, 0.001f);
524 EXPECT_NEAR(720.792f, quadpoints.y1, 0.001f);
525 EXPECT_NEAR(132.055f, quadpoints.x4, 0.001f);
526 EXPECT_NEAR(704.796f, quadpoints.y4, 0.001f);
527
528 // Check that updating the attachment points would succeed.
529 quadpoints.x1 -= 50.f;
530 quadpoints.x2 -= 50.f;
531 quadpoints.x3 -= 50.f;
532 quadpoints.x4 -= 50.f;
Ralf Sippl16381792018-04-12 21:20:26 +0000533 ASSERT_TRUE(FPDFAnnot_SetAttachmentPoints(annot.get(), 0, &quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000534 FS_QUADPOINTSF new_quadpoints;
Ralf Sippl16381792018-04-12 21:20:26 +0000535 ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot.get(), 0, &new_quadpoints));
Lei Zhanga21d5932018-02-05 18:28:38 +0000536 EXPECT_EQ(quadpoints.x1, new_quadpoints.x1);
537 EXPECT_EQ(quadpoints.y1, new_quadpoints.y1);
538 EXPECT_EQ(quadpoints.x4, new_quadpoints.x4);
539 EXPECT_EQ(quadpoints.y4, new_quadpoints.y4);
540
541 // Check that updating quadpoints does not change the annotation's position.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000542 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000543 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000544 CompareBitmap(bitmap.get(), 612, 792, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000545 }
Lei Zhanga21d5932018-02-05 18:28:38 +0000546
547 // Verify its annotation rectangle.
548 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
549 EXPECT_NEAR(67.7299f, rect.left, 0.001f);
550 EXPECT_NEAR(704.296f, rect.bottom, 0.001f);
551 EXPECT_NEAR(136.325f, rect.right, 0.001f);
552 EXPECT_NEAR(721.292f, rect.top, 0.001f);
553
554 // Check that updating the rectangle would succeed.
555 rect.left -= 60.f;
556 rect.right -= 60.f;
557 ASSERT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
558 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &new_rect));
559 EXPECT_EQ(rect.right, new_rect.right);
560 }
Jane Liu06462752017-06-27 16:41:14 -0400561
Jane Liub370e5a2017-08-16 13:24:58 -0400562 // Check that updating the rectangle changes the annotation's position.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000563 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000564 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000565 CompareBitmap(bitmap.get(), 612, 792, kMd5ModifiedHighlight);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000566 }
Jane Liub370e5a2017-08-16 13:24:58 -0400567
Lei Zhanga21d5932018-02-05 18:28:38 +0000568 {
569 // Retrieve the square annotation which has its AP stream already defined.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000570 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +0000571 ASSERT_TRUE(annot);
572 EXPECT_EQ(FPDF_ANNOT_SQUARE, FPDFAnnot_GetSubtype(annot.get()));
Jane Liu06462752017-06-27 16:41:14 -0400573
Lei Zhanga21d5932018-02-05 18:28:38 +0000574 // Check that updating the rectangle would succeed.
575 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
576 rect.left += 70.f;
577 rect.right += 70.f;
578 ASSERT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
579 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &new_rect));
580 EXPECT_EQ(rect.right, new_rect.right);
Jane Liu06462752017-06-27 16:41:14 -0400581
Lei Zhanga21d5932018-02-05 18:28:38 +0000582 // Check that updating the rectangle changes the square annotation's
583 // position.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000584 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000585 CompareBitmap(bitmap.get(), 612, 792, kMd5ModifiedSquare);
Lei Zhanga21d5932018-02-05 18:28:38 +0000586 }
Jane Liub370e5a2017-08-16 13:24:58 -0400587
Jane Liu06462752017-06-27 16:41:14 -0400588 UnloadPage(page);
589}
Jane Liu8ce58f52017-06-29 13:40:22 -0400590
Lei Zhangab41f252018-12-23 03:10:50 +0000591TEST_F(FPDFAnnotEmbedderTest, CountAttachmentPoints) {
Henrique Nakashima5098b252018-03-26 21:46:00 +0000592 // Open a file with multiline markup annotations.
593 ASSERT_TRUE(OpenDocument("annotation_markup_multiline_no_ap.pdf"));
594 FPDF_PAGE page = LoadPage(0);
595 ASSERT_TRUE(page);
596 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000597 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Henrique Nakashima5098b252018-03-26 21:46:00 +0000598 ASSERT_TRUE(annot);
599
600 // This is a three line annotation.
601 EXPECT_EQ(3u, FPDFAnnot_CountAttachmentPoints(annot.get()));
602 }
603 UnloadPage(page);
604
605 // null annotation should return 0
606 EXPECT_EQ(0u, FPDFAnnot_CountAttachmentPoints(nullptr));
607}
608
Lei Zhangab41f252018-12-23 03:10:50 +0000609TEST_F(FPDFAnnotEmbedderTest, RemoveAnnotation) {
Jane Liu8ce58f52017-06-29 13:40:22 -0400610 // Open a file with 3 annotations on its first page.
611 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
Tom Sepez507d0192018-11-07 16:37:51 +0000612 FPDF_PAGE page = LoadPageNoEvents(0);
Jane Liu8ce58f52017-06-29 13:40:22 -0400613 ASSERT_TRUE(page);
614 EXPECT_EQ(3, FPDFPage_GetAnnotCount(page));
615
Jane Liu0c6b07d2017-08-15 10:50:22 -0400616 FS_RECTF rect;
Jane Liu8ce58f52017-06-29 13:40:22 -0400617
Lei Zhanga21d5932018-02-05 18:28:38 +0000618 // Check that the annotations have the expected rectangle coordinates.
619 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000620 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000621 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
622 EXPECT_NEAR(86.1971f, rect.left, 0.001f);
623 }
Jane Liu8ce58f52017-06-29 13:40:22 -0400624
Lei Zhanga21d5932018-02-05 18:28:38 +0000625 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000626 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 1));
Lei Zhanga21d5932018-02-05 18:28:38 +0000627 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
628 EXPECT_NEAR(149.8127f, rect.left, 0.001f);
629 }
630
631 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000632 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +0000633 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
634 EXPECT_NEAR(351.8204f, rect.left, 0.001f);
635 }
Jane Liu8ce58f52017-06-29 13:40:22 -0400636
637 // Check that nothing happens when attempting to remove an annotation with an
638 // out-of-bound index.
639 EXPECT_FALSE(FPDFPage_RemoveAnnot(page, 4));
640 EXPECT_FALSE(FPDFPage_RemoveAnnot(page, -1));
641 EXPECT_EQ(3, FPDFPage_GetAnnotCount(page));
642
643 // Remove the second annotation.
644 EXPECT_TRUE(FPDFPage_RemoveAnnot(page, 1));
645 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
646 EXPECT_FALSE(FPDFPage_GetAnnot(page, 2));
647
648 // Save the document, closing the page and document.
649 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Tom Sepez507d0192018-11-07 16:37:51 +0000650 UnloadPageNoEvents(page);
Jane Liu8ce58f52017-06-29 13:40:22 -0400651
Dan Sinclair04e4dc82017-10-18 12:17:14 -0400652 // TODO(npm): VerifySavedRendering changes annot rect dimensions by 1??
Jane Liu8ce58f52017-06-29 13:40:22 -0400653 // Open the saved document.
654 std::string new_file = GetString();
655 FPDF_FILEACCESS file_access;
656 memset(&file_access, 0, sizeof(file_access));
657 file_access.m_FileLen = new_file.size();
658 file_access.m_GetBlock = GetBlockFromString;
659 file_access.m_Param = &new_file;
660 FPDF_DOCUMENT new_doc = FPDF_LoadCustomDocument(&file_access, nullptr);
661 ASSERT_TRUE(new_doc);
662 FPDF_PAGE new_page = FPDF_LoadPage(new_doc, 0);
663 ASSERT_TRUE(new_page);
664
665 // Check that the saved document has 2 annotations on the first page.
666 EXPECT_EQ(2, FPDFPage_GetAnnotCount(new_page));
667
Lei Zhanga21d5932018-02-05 18:28:38 +0000668 // Check that the remaining 2 annotations are the original 1st and 3rd ones
669 // by verifying their rectangle coordinates.
670 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000671 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(new_page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000672 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
673 EXPECT_NEAR(86.1971f, rect.left, 0.001f);
674 }
Jane Liu8ce58f52017-06-29 13:40:22 -0400675
Lei Zhanga21d5932018-02-05 18:28:38 +0000676 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000677 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(new_page, 1));
Lei Zhanga21d5932018-02-05 18:28:38 +0000678 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &rect));
679 EXPECT_NEAR(351.8204f, rect.left, 0.001f);
680 }
Jane Liubaa7ff42017-06-29 19:18:23 -0400681 FPDF_ClosePage(new_page);
682 FPDF_CloseDocument(new_doc);
683}
Jane Liu8ce58f52017-06-29 13:40:22 -0400684
Lei Zhangab41f252018-12-23 03:10:50 +0000685TEST_F(FPDFAnnotEmbedderTest, AddAndModifyPath) {
Lei Zhange4cdac52019-04-30 16:45:57 +0000686#if defined(OS_MACOSX)
Lei Zhang4f556b82019-04-08 16:32:41 +0000687 static const char kMd5Original[] = "c35408717759562d1f8bf33d317483d2";
688 static const char kMd5ModifiedPath[] = "9059723a045e17478753d2f0eb33bc03";
689 static const char kMd5TwoPaths[] = "7eed0cfba780f1d4dd8068f717d3a6bf";
690 static const char kMd5NewAnnot[] = "1de8212d43b7066a6df042095c2aca61";
Lei Zhang5e2c51c2018-07-27 22:33:34 +0000691#elif _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
Lei Zhang4f556b82019-04-08 16:32:41 +0000692 static const char kMd5Original[] = "6f3cc2dd37479ce7cc072bfb0c63c275";
693 static const char kMd5ModifiedPath[] = "c0c2eb2aba73ad15b3240e342fbe0d72";
694 static const char kMd5TwoPaths[] = "2306bf04915fe001b5f4726843d184c8";
695 static const char kMd5NewAnnot[] = "64a319f145768cb09944d2109efe394e";
Jane Liubaa7ff42017-06-29 19:18:23 -0400696#else
Lei Zhang4f556b82019-04-08 16:32:41 +0000697 static const char kMd5Original[] = "964f89bbe8911e540a465cf1a64b7f7e";
698 static const char kMd5ModifiedPath[] = "9a38048fb3ac1b2c9a4b34139caa993c";
699 static const char kMd5TwoPaths[] = "ece3d4df54b3395d6a2bf7a29b17239c";
700 static const char kMd5NewAnnot[] = "4299493de84c249f42f220f30f2bbb67";
Jane Liubaa7ff42017-06-29 19:18:23 -0400701#endif
702
703 // Open a file with two annotations and load its first page.
704 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000705 FPDF_PAGE page = LoadPage(0);
Jane Liubaa7ff42017-06-29 19:18:23 -0400706 ASSERT_TRUE(page);
707 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
708
709 // Check that the page renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000710 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000711 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000712 CompareBitmap(bitmap.get(), 595, 842, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000713 }
Jane Liubaa7ff42017-06-29 19:18:23 -0400714
Lei Zhanga21d5932018-02-05 18:28:38 +0000715 {
716 // Retrieve the stamp annotation which has its AP stream already defined.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000717 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000718 ASSERT_TRUE(annot);
Jane Liubaa7ff42017-06-29 19:18:23 -0400719
Lei Zhanga21d5932018-02-05 18:28:38 +0000720 // Check that this annotation has one path object and retrieve it.
721 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000722 ASSERT_EQ(32, FPDFPage_CountObjects(page));
Lei Zhanga21d5932018-02-05 18:28:38 +0000723 FPDF_PAGEOBJECT path = FPDFAnnot_GetObject(annot.get(), 1);
724 EXPECT_FALSE(path);
725 path = FPDFAnnot_GetObject(annot.get(), 0);
726 EXPECT_EQ(FPDF_PAGEOBJ_PATH, FPDFPageObj_GetType(path));
727 EXPECT_TRUE(path);
Jane Liubaa7ff42017-06-29 19:18:23 -0400728
Lei Zhanga21d5932018-02-05 18:28:38 +0000729 // Modify the color of the path object.
730 EXPECT_TRUE(FPDFPath_SetStrokeColor(path, 0, 0, 0, 255));
731 EXPECT_TRUE(FPDFAnnot_UpdateObject(annot.get(), path));
Jane Liubaa7ff42017-06-29 19:18:23 -0400732
Lei Zhanga21d5932018-02-05 18:28:38 +0000733 // Check that the page with the modified annotation renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000734 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000735 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000736 CompareBitmap(bitmap.get(), 595, 842, kMd5ModifiedPath);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000737 }
Jane Liu7a9a38b2017-07-11 13:47:37 -0400738
Lei Zhanga21d5932018-02-05 18:28:38 +0000739 // Add a second path object to the same annotation.
740 FPDF_PAGEOBJECT dot = FPDFPageObj_CreateNewPath(7, 84);
741 EXPECT_TRUE(FPDFPath_BezierTo(dot, 9, 86, 10, 87, 11, 88));
742 EXPECT_TRUE(FPDFPath_SetStrokeColor(dot, 255, 0, 0, 100));
743 EXPECT_TRUE(FPDFPath_SetStrokeWidth(dot, 14));
744 EXPECT_TRUE(FPDFPath_SetDrawMode(dot, 0, 1));
745 EXPECT_TRUE(FPDFAnnot_AppendObject(annot.get(), dot));
746 EXPECT_EQ(2, FPDFAnnot_GetObjectCount(annot.get()));
Jane Liu7a9a38b2017-07-11 13:47:37 -0400747
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000748 // The object is in the annontation, not in the page, so the page object
749 // array should not change.
750 ASSERT_EQ(32, FPDFPage_CountObjects(page));
751
Lei Zhanga21d5932018-02-05 18:28:38 +0000752 // Check that the page with an annotation with two paths renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000753 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000754 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000755 CompareBitmap(bitmap.get(), 595, 842, kMd5TwoPaths);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000756 }
Jane Liu7a9a38b2017-07-11 13:47:37 -0400757
Lei Zhanga21d5932018-02-05 18:28:38 +0000758 // Delete the newly added path object.
759 EXPECT_TRUE(FPDFAnnot_RemoveObject(annot.get(), 1));
760 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
Henrique Nakashima35841fa2018-03-15 15:25:16 +0000761 ASSERT_EQ(32, FPDFPage_CountObjects(page));
Lei Zhanga21d5932018-02-05 18:28:38 +0000762 }
Jane Liu7a9a38b2017-07-11 13:47:37 -0400763
764 // Check that the page renders the same as before.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000765 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000766 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000767 CompareBitmap(bitmap.get(), 595, 842, kMd5ModifiedPath);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000768 }
Jane Liubaa7ff42017-06-29 19:18:23 -0400769
Jane Liubaa7ff42017-06-29 19:18:23 -0400770 FS_RECTF rect;
Jane Liubaa7ff42017-06-29 19:18:23 -0400771
Lei Zhanga21d5932018-02-05 18:28:38 +0000772 {
773 // Create another stamp annotation and set its annotation rectangle.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000774 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP));
Lei Zhanga21d5932018-02-05 18:28:38 +0000775 ASSERT_TRUE(annot);
776 rect.left = 200.f;
777 rect.bottom = 400.f;
778 rect.right = 500.f;
779 rect.top = 600.f;
780 EXPECT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
Jane Liubaa7ff42017-06-29 19:18:23 -0400781
Lei Zhanga21d5932018-02-05 18:28:38 +0000782 // Add a new path to the annotation.
783 FPDF_PAGEOBJECT check = FPDFPageObj_CreateNewPath(200, 500);
784 EXPECT_TRUE(FPDFPath_LineTo(check, 300, 400));
785 EXPECT_TRUE(FPDFPath_LineTo(check, 500, 600));
786 EXPECT_TRUE(FPDFPath_MoveTo(check, 350, 550));
787 EXPECT_TRUE(FPDFPath_LineTo(check, 450, 450));
788 EXPECT_TRUE(FPDFPath_SetStrokeColor(check, 0, 255, 255, 180));
789 EXPECT_TRUE(FPDFPath_SetStrokeWidth(check, 8.35f));
790 EXPECT_TRUE(FPDFPath_SetDrawMode(check, 0, 1));
791 EXPECT_TRUE(FPDFAnnot_AppendObject(annot.get(), check));
792 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
793
794 // Check that the annotation's bounding box came from its rectangle.
795 FS_RECTF new_rect;
796 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &new_rect));
797 EXPECT_EQ(rect.left, new_rect.left);
798 EXPECT_EQ(rect.bottom, new_rect.bottom);
799 EXPECT_EQ(rect.right, new_rect.right);
800 EXPECT_EQ(rect.top, new_rect.top);
801 }
Jane Liubaa7ff42017-06-29 19:18:23 -0400802
803 // Save the document, closing the page and document.
Jane Liubaa7ff42017-06-29 19:18:23 -0400804 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang75c81712018-02-08 17:22:39 +0000805 UnloadPage(page);
Jane Liubaa7ff42017-06-29 19:18:23 -0400806
807 // Open the saved document.
Lei Zhang0b494052019-01-31 21:41:15 +0000808 ASSERT_TRUE(OpenSavedDocument());
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000809 page = LoadSavedPage(0);
Lei Zhang4f556b82019-04-08 16:32:41 +0000810 VerifySavedRendering(page, 595, 842, kMd5NewAnnot);
Jane Liubaa7ff42017-06-29 19:18:23 -0400811
Jane Liu36567742017-07-06 11:13:35 -0400812 // Check that the document has a correct count of annotations and objects.
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000813 EXPECT_EQ(3, FPDFPage_GetAnnotCount(page));
Jane Liubaa7ff42017-06-29 19:18:23 -0400814
Lei Zhanga21d5932018-02-05 18:28:38 +0000815 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000816 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +0000817 ASSERT_TRUE(annot);
818 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
Jane Liubaa7ff42017-06-29 19:18:23 -0400819
Lei Zhanga21d5932018-02-05 18:28:38 +0000820 // Check that the new annotation's rectangle is as defined.
821 FS_RECTF new_rect;
822 ASSERT_TRUE(FPDFAnnot_GetRect(annot.get(), &new_rect));
823 EXPECT_EQ(rect.left, new_rect.left);
824 EXPECT_EQ(rect.bottom, new_rect.bottom);
825 EXPECT_EQ(rect.right, new_rect.right);
826 EXPECT_EQ(rect.top, new_rect.top);
827 }
828
Henrique Nakashima8baea3c2017-11-10 20:27:23 +0000829 CloseSavedPage(page);
Dan Sinclair04e4dc82017-10-18 12:17:14 -0400830 CloseSavedDocument();
Jane Liu8ce58f52017-06-29 13:40:22 -0400831}
Jane Liub137e752017-07-05 15:04:33 -0400832
Lei Zhangab41f252018-12-23 03:10:50 +0000833TEST_F(FPDFAnnotEmbedderTest, ModifyAnnotationFlags) {
Jane Liub137e752017-07-05 15:04:33 -0400834 // Open a file with an annotation and load its first page.
835 ASSERT_TRUE(OpenDocument("annotation_highlight_rollover_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000836 FPDF_PAGE page = LoadPage(0);
Jane Liub137e752017-07-05 15:04:33 -0400837 ASSERT_TRUE(page);
838
839 // Check that the page renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000840 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000841 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000842 CompareBitmap(bitmap.get(), 612, 792, "dc98f06da047bd8aabfa99562d2cbd1e");
843 }
Jane Liub137e752017-07-05 15:04:33 -0400844
Lei Zhanga21d5932018-02-05 18:28:38 +0000845 {
846 // Retrieve the annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000847 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +0000848 ASSERT_TRUE(annot);
Jane Liub137e752017-07-05 15:04:33 -0400849
Lei Zhanga21d5932018-02-05 18:28:38 +0000850 // Check that the original flag values are as expected.
851 int flags = FPDFAnnot_GetFlags(annot.get());
852 EXPECT_FALSE(flags & FPDF_ANNOT_FLAG_HIDDEN);
853 EXPECT_TRUE(flags & FPDF_ANNOT_FLAG_PRINT);
Jane Liub137e752017-07-05 15:04:33 -0400854
Lei Zhanga21d5932018-02-05 18:28:38 +0000855 // Set the HIDDEN flag.
856 flags |= FPDF_ANNOT_FLAG_HIDDEN;
857 EXPECT_TRUE(FPDFAnnot_SetFlags(annot.get(), flags));
858 flags = FPDFAnnot_GetFlags(annot.get());
859 EXPECT_TRUE(flags & FPDF_ANNOT_FLAG_HIDDEN);
860 EXPECT_TRUE(flags & FPDF_ANNOT_FLAG_PRINT);
Jane Liub137e752017-07-05 15:04:33 -0400861
Lei Zhanga21d5932018-02-05 18:28:38 +0000862 // Check that the page renders correctly without rendering the annotation.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000863 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000864 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000865 CompareBitmap(bitmap.get(), 612, 792, "1940568c9ba33bac5d0b1ee9558c76b3");
866 }
Jane Liub137e752017-07-05 15:04:33 -0400867
Lei Zhanga21d5932018-02-05 18:28:38 +0000868 // Unset the HIDDEN flag.
869 EXPECT_TRUE(FPDFAnnot_SetFlags(annot.get(), FPDF_ANNOT_FLAG_NONE));
870 EXPECT_FALSE(FPDFAnnot_GetFlags(annot.get()));
871 flags &= ~FPDF_ANNOT_FLAG_HIDDEN;
872 EXPECT_TRUE(FPDFAnnot_SetFlags(annot.get(), flags));
873 flags = FPDFAnnot_GetFlags(annot.get());
874 EXPECT_FALSE(flags & FPDF_ANNOT_FLAG_HIDDEN);
875 EXPECT_TRUE(flags & FPDF_ANNOT_FLAG_PRINT);
Jane Liub137e752017-07-05 15:04:33 -0400876
Lei Zhanga21d5932018-02-05 18:28:38 +0000877 // Check that the page renders correctly as before.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000878 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000879 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000880 CompareBitmap(bitmap.get(), 612, 792, "dc98f06da047bd8aabfa99562d2cbd1e");
881 }
Lei Zhanga21d5932018-02-05 18:28:38 +0000882 }
Jane Liub137e752017-07-05 15:04:33 -0400883
Jane Liub137e752017-07-05 15:04:33 -0400884 UnloadPage(page);
885}
Jane Liu36567742017-07-06 11:13:35 -0400886
Lei Zhangab41f252018-12-23 03:10:50 +0000887TEST_F(FPDFAnnotEmbedderTest, AddAndModifyImage) {
Lei Zhange4cdac52019-04-30 16:45:57 +0000888#if defined(OS_MACOSX)
Lei Zhang4f556b82019-04-08 16:32:41 +0000889 static const char kMd5Original[] = "c35408717759562d1f8bf33d317483d2";
890 static const char kMd5NewImage[] = "ff012f5697436dfcaec25b32d1333596";
891 static const char kMd5ModifiedImage[] = "86cf8cb2755a7a2046a543e66d9c1e61";
Lei Zhang5e2c51c2018-07-27 22:33:34 +0000892#elif _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
Lei Zhang4f556b82019-04-08 16:32:41 +0000893 static const char kMd5Original[] = "6f3cc2dd37479ce7cc072bfb0c63c275";
894 static const char kMd5NewImage[] = "d19c6fcfd9a170802fcfb9adfa13557e";
895 static const char kMd5ModifiedImage[] = "1273cf2363570a50d1aa0c95b1318197";
Jane Liu36567742017-07-06 11:13:35 -0400896#else
Lei Zhang4f556b82019-04-08 16:32:41 +0000897 static const char kMd5Original[] = "964f89bbe8911e540a465cf1a64b7f7e";
898 static const char kMd5NewImage[] = "9ea8732dc9d579f68853f16892856208";
899 static const char kMd5ModifiedImage[] = "74239d2a8c55c9de1dbb9cd8781895aa";
Jane Liu36567742017-07-06 11:13:35 -0400900#endif
901
902 // Open a file with two annotations and load its first page.
903 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000904 FPDF_PAGE page = LoadPage(0);
Jane Liu36567742017-07-06 11:13:35 -0400905 ASSERT_TRUE(page);
906 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
907
908 // Check that the page renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000909 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000910 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000911 CompareBitmap(bitmap.get(), 595, 842, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000912 }
Jane Liu36567742017-07-06 11:13:35 -0400913
Jane Liu36567742017-07-06 11:13:35 -0400914 constexpr int kBitmapSize = 200;
Lei Zhanga21d5932018-02-05 18:28:38 +0000915 FPDF_BITMAP image_bitmap;
916
917 {
918 // Create a stamp annotation and set its annotation rectangle.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000919 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP));
Lei Zhanga21d5932018-02-05 18:28:38 +0000920 ASSERT_TRUE(annot);
921 FS_RECTF rect;
922 rect.left = 200.f;
923 rect.bottom = 600.f;
924 rect.right = 400.f;
925 rect.top = 800.f;
926 EXPECT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
927
928 // Add a solid-color translucent image object to the new annotation.
929 image_bitmap = FPDFBitmap_Create(kBitmapSize, kBitmapSize, 1);
930 FPDFBitmap_FillRect(image_bitmap, 0, 0, kBitmapSize, kBitmapSize,
931 0xeeeecccc);
932 EXPECT_EQ(kBitmapSize, FPDFBitmap_GetWidth(image_bitmap));
933 EXPECT_EQ(kBitmapSize, FPDFBitmap_GetHeight(image_bitmap));
934 FPDF_PAGEOBJECT image_object = FPDFPageObj_NewImageObj(document());
935 ASSERT_TRUE(FPDFImageObj_SetBitmap(&page, 0, image_object, image_bitmap));
936 ASSERT_TRUE(FPDFImageObj_SetMatrix(image_object, kBitmapSize, 0, 0,
937 kBitmapSize, 0, 0));
938 FPDFPageObj_Transform(image_object, 1, 0, 0, 1, 200, 600);
939 EXPECT_TRUE(FPDFAnnot_AppendObject(annot.get(), image_object));
940 }
Jane Liu36567742017-07-06 11:13:35 -0400941
942 // Check that the page renders correctly with the new image object.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000943 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000944 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000945 CompareBitmap(bitmap.get(), 595, 842, kMd5NewImage);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000946 }
Jane Liu36567742017-07-06 11:13:35 -0400947
Lei Zhanga21d5932018-02-05 18:28:38 +0000948 {
949 // Retrieve the newly added stamp annotation and its image object.
Tom Sepeze08d2b12018-04-25 18:49:32 +0000950 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +0000951 ASSERT_TRUE(annot);
952 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
953 FPDF_PAGEOBJECT image_object = FPDFAnnot_GetObject(annot.get(), 0);
954 EXPECT_EQ(FPDF_PAGEOBJ_IMAGE, FPDFPageObj_GetType(image_object));
Jane Liu36567742017-07-06 11:13:35 -0400955
Lei Zhanga21d5932018-02-05 18:28:38 +0000956 // Modify the image in the new annotation.
957 FPDFBitmap_FillRect(image_bitmap, 0, 0, kBitmapSize, kBitmapSize,
958 0xff000000);
959 ASSERT_TRUE(FPDFImageObj_SetBitmap(&page, 0, image_object, image_bitmap));
960 EXPECT_TRUE(FPDFAnnot_UpdateObject(annot.get(), image_object));
961 }
Jane Liu36567742017-07-06 11:13:35 -0400962
963 // Save the document, closing the page and document.
964 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang75c81712018-02-08 17:22:39 +0000965 UnloadPage(page);
Dan Sinclair04e4dc82017-10-18 12:17:14 -0400966 FPDFBitmap_Destroy(image_bitmap);
Jane Liu36567742017-07-06 11:13:35 -0400967
968 // Test that the saved document renders the modified image object correctly.
Lei Zhang4f556b82019-04-08 16:32:41 +0000969 VerifySavedDocument(595, 842, kMd5ModifiedImage);
Jane Liu36567742017-07-06 11:13:35 -0400970}
971
Lei Zhangab41f252018-12-23 03:10:50 +0000972TEST_F(FPDFAnnotEmbedderTest, AddAndModifyText) {
Lei Zhange4cdac52019-04-30 16:45:57 +0000973#if defined(OS_MACOSX)
Lei Zhang4f556b82019-04-08 16:32:41 +0000974 static const char kMd5Original[] = "c35408717759562d1f8bf33d317483d2";
975 static const char kMd5NewText[] = "60031c1b0330cf1e1575f7d46687d429";
976 static const char kMd5ModifiedText[] = "79f5cfb0b07caaf936f65f6a7a57ce77";
Lei Zhang5e2c51c2018-07-27 22:33:34 +0000977#elif _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
Lei Zhang4f556b82019-04-08 16:32:41 +0000978 static const char kMd5Original[] = "6f3cc2dd37479ce7cc072bfb0c63c275";
979 static const char kMd5NewText[] = "87d55e09f9096de7e6552f5ae79afd3b";
980 static const char kMd5ModifiedText[] = "26e94fbd3af4b1e65479327507600114";
Jane Liu36567742017-07-06 11:13:35 -0400981#else
Lei Zhang4f556b82019-04-08 16:32:41 +0000982 static const char kMd5Original[] = "964f89bbe8911e540a465cf1a64b7f7e";
983 static const char kMd5NewText[] = "30f3f5b989612ca03827d95f184f0979";
984 static const char kMd5ModifiedText[] = "076c8f24a09ddc0e49f7e758edead6f0";
Jane Liu36567742017-07-06 11:13:35 -0400985#endif
986
987 // Open a file with two annotations and load its first page.
988 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +0000989 FPDF_PAGE page = LoadPage(0);
Jane Liu36567742017-07-06 11:13:35 -0400990 ASSERT_TRUE(page);
991 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
992
993 // Check that the page renders correctly.
Lei Zhangc113c7a2018-02-12 14:58:44 +0000994 {
Tom Sepeze08d2b12018-04-25 18:49:32 +0000995 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +0000996 CompareBitmap(bitmap.get(), 595, 842, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +0000997 }
Jane Liu36567742017-07-06 11:13:35 -0400998
Lei Zhanga21d5932018-02-05 18:28:38 +0000999 {
1000 // Create a stamp annotation and set its annotation rectangle.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001001 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP));
Lei Zhanga21d5932018-02-05 18:28:38 +00001002 ASSERT_TRUE(annot);
1003 FS_RECTF rect;
1004 rect.left = 200.f;
1005 rect.bottom = 550.f;
1006 rect.right = 450.f;
1007 rect.top = 650.f;
1008 EXPECT_TRUE(FPDFAnnot_SetRect(annot.get(), &rect));
Jane Liu36567742017-07-06 11:13:35 -04001009
Lei Zhanga21d5932018-02-05 18:28:38 +00001010 // Add a translucent text object to the new annotation.
1011 FPDF_PAGEOBJECT text_object =
1012 FPDFPageObj_NewTextObj(document(), "Arial", 12.0f);
1013 EXPECT_TRUE(text_object);
Lei Zhangf0f67682019-04-08 17:03:21 +00001014 ScopedFPDFWideString text =
Lei Zhanga21d5932018-02-05 18:28:38 +00001015 GetFPDFWideString(L"I'm a translucent text laying on other text.");
1016 EXPECT_TRUE(FPDFText_SetText(text_object, text.get()));
1017 EXPECT_TRUE(FPDFText_SetFillColor(text_object, 0, 0, 255, 150));
1018 FPDFPageObj_Transform(text_object, 1, 0, 0, 1, 200, 600);
1019 EXPECT_TRUE(FPDFAnnot_AppendObject(annot.get(), text_object));
1020 }
Jane Liu36567742017-07-06 11:13:35 -04001021
1022 // Check that the page renders correctly with the new text object.
Lei Zhangc113c7a2018-02-12 14:58:44 +00001023 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001024 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +00001025 CompareBitmap(bitmap.get(), 595, 842, kMd5NewText);
Lei Zhangc113c7a2018-02-12 14:58:44 +00001026 }
Jane Liu36567742017-07-06 11:13:35 -04001027
Lei Zhanga21d5932018-02-05 18:28:38 +00001028 {
1029 // Retrieve the newly added stamp annotation and its text object.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001030 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +00001031 ASSERT_TRUE(annot);
1032 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot.get()));
1033 FPDF_PAGEOBJECT text_object = FPDFAnnot_GetObject(annot.get(), 0);
1034 EXPECT_EQ(FPDF_PAGEOBJ_TEXT, FPDFPageObj_GetType(text_object));
Jane Liu36567742017-07-06 11:13:35 -04001035
Lei Zhanga21d5932018-02-05 18:28:38 +00001036 // Modify the text in the new annotation.
Lei Zhangf0f67682019-04-08 17:03:21 +00001037 ScopedFPDFWideString new_text = GetFPDFWideString(L"New text!");
Lei Zhanga21d5932018-02-05 18:28:38 +00001038 EXPECT_TRUE(FPDFText_SetText(text_object, new_text.get()));
1039 EXPECT_TRUE(FPDFAnnot_UpdateObject(annot.get(), text_object));
1040 }
Jane Liu36567742017-07-06 11:13:35 -04001041
1042 // Check that the page renders correctly with the modified text object.
Lei Zhangc113c7a2018-02-12 14:58:44 +00001043 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001044 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +00001045 CompareBitmap(bitmap.get(), 595, 842, kMd5ModifiedText);
Lei Zhangc113c7a2018-02-12 14:58:44 +00001046 }
Jane Liu36567742017-07-06 11:13:35 -04001047
1048 // Remove the new annotation, and check that the page renders as before.
1049 EXPECT_TRUE(FPDFPage_RemoveAnnot(page, 2));
Lei Zhangc113c7a2018-02-12 14:58:44 +00001050 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001051 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
Lei Zhang4f556b82019-04-08 16:32:41 +00001052 CompareBitmap(bitmap.get(), 595, 842, kMd5Original);
Lei Zhangc113c7a2018-02-12 14:58:44 +00001053 }
Jane Liu36567742017-07-06 11:13:35 -04001054
1055 UnloadPage(page);
1056}
Jane Liu2e1a32b2017-07-06 12:01:25 -04001057
Lei Zhangab41f252018-12-23 03:10:50 +00001058TEST_F(FPDFAnnotEmbedderTest, GetSetStringValue) {
Jane Liu2e1a32b2017-07-06 12:01:25 -04001059 // Open a file with four annotations and load its first page.
1060 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001061 FPDF_PAGE page = LoadPage(0);
Jane Liu2e1a32b2017-07-06 12:01:25 -04001062 ASSERT_TRUE(page);
1063
Lei Zhang4f556b82019-04-08 16:32:41 +00001064 static const wchar_t kNewDate[] = L"D:201706282359Z00'00'";
Jane Liu2e1a32b2017-07-06 12:01:25 -04001065
Lei Zhanga21d5932018-02-05 18:28:38 +00001066 {
1067 // Retrieve the first annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001068 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001069 ASSERT_TRUE(annot);
1070
1071 // Check that a non-existent key does not exist.
1072 EXPECT_FALSE(FPDFAnnot_HasKey(annot.get(), "none"));
1073
1074 // Check that the string value of a non-string dictionary entry is empty.
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001075 EXPECT_TRUE(FPDFAnnot_HasKey(annot.get(), pdfium::annotation::kAP));
Lei Zhanga21d5932018-02-05 18:28:38 +00001076 EXPECT_EQ(FPDF_OBJECT_REFERENCE,
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001077 FPDFAnnot_GetValueType(annot.get(), pdfium::annotation::kAP));
1078 EXPECT_EQ(2u, FPDFAnnot_GetStringValue(annot.get(), pdfium::annotation::kAP,
1079 nullptr, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001080
1081 // Check that the string value of the hash is correct.
Lei Zhang4f556b82019-04-08 16:32:41 +00001082 static const char kHashKey[] = "AAPL:Hash";
Lei Zhanga21d5932018-02-05 18:28:38 +00001083 EXPECT_EQ(FPDF_OBJECT_NAME, FPDFAnnot_GetValueType(annot.get(), kHashKey));
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001084 unsigned long length_bytes =
Lei Zhanga21d5932018-02-05 18:28:38 +00001085 FPDFAnnot_GetStringValue(annot.get(), kHashKey, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001086 ASSERT_EQ(66u, length_bytes);
1087 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
1088 EXPECT_EQ(66u, FPDFAnnot_GetStringValue(annot.get(), kHashKey, buf.data(),
1089 length_bytes));
1090 EXPECT_EQ(L"395fbcb98d558681742f30683a62a2ad",
1091 GetPlatformWString(buf.data()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001092
1093 // Check that the string value of the modified date is correct.
1094 EXPECT_EQ(FPDF_OBJECT_NAME, FPDFAnnot_GetValueType(annot.get(), kHashKey));
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001095 length_bytes = FPDFAnnot_GetStringValue(annot.get(), pdfium::annotation::kM,
1096 nullptr, 0);
1097 ASSERT_EQ(44u, length_bytes);
1098 buf = GetFPDFWideStringBuffer(length_bytes);
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001099 EXPECT_EQ(44u, FPDFAnnot_GetStringValue(annot.get(), pdfium::annotation::kM,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001100 buf.data(), length_bytes));
1101 EXPECT_EQ(L"D:201706071721Z00'00'", GetPlatformWString(buf.data()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001102
1103 // Update the date entry for the annotation.
Lei Zhangf0f67682019-04-08 17:03:21 +00001104 ScopedFPDFWideString text = GetFPDFWideString(kNewDate);
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001105 EXPECT_TRUE(FPDFAnnot_SetStringValue(annot.get(), pdfium::annotation::kM,
1106 text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001107 }
Jane Liu2e1a32b2017-07-06 12:01:25 -04001108
1109 // Save the document, closing the page and document.
Jane Liu2e1a32b2017-07-06 12:01:25 -04001110 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang75c81712018-02-08 17:22:39 +00001111 UnloadPage(page);
Jane Liu2e1a32b2017-07-06 12:01:25 -04001112
Lei Zhange4cdac52019-04-30 16:45:57 +00001113#if defined(OS_MACOSX)
Lei Zhang4f556b82019-04-08 16:32:41 +00001114 static const char kMd5[] = "4d64e61c9c0f8c60ab3cc3234bb73b1c";
Lei Zhang5e2c51c2018-07-27 22:33:34 +00001115#elif _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
Lei Zhang4f556b82019-04-08 16:32:41 +00001116 static const char kMd5[] = "9ee141f698c3fcb56c050dffd6c82624";
Jane Liu2e1a32b2017-07-06 12:01:25 -04001117#else
Lei Zhang4f556b82019-04-08 16:32:41 +00001118 static const char kMd5[] = "c96ee1f316d7f5a1b154de9f9d467f01";
Jane Liu2e1a32b2017-07-06 12:01:25 -04001119#endif
Dan Sinclair971a6742018-03-28 19:23:25 +00001120
1121 // Open the saved annotation.
Lei Zhang0b494052019-01-31 21:41:15 +00001122 ASSERT_TRUE(OpenSavedDocument());
Henrique Nakashima8baea3c2017-11-10 20:27:23 +00001123 page = LoadSavedPage(0);
Lei Zhang4f556b82019-04-08 16:32:41 +00001124 VerifySavedRendering(page, 595, 842, kMd5);
Lei Zhanga21d5932018-02-05 18:28:38 +00001125 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001126 ScopedFPDFAnnotation new_annot(FPDFPage_GetAnnot(page, 0));
Jane Liu2e1a32b2017-07-06 12:01:25 -04001127
Lei Zhanga21d5932018-02-05 18:28:38 +00001128 // Check that the string value of the modified date is the newly-set value.
1129 EXPECT_EQ(FPDF_OBJECT_STRING,
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001130 FPDFAnnot_GetValueType(new_annot.get(), pdfium::annotation::kM));
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001131 unsigned long length_bytes = FPDFAnnot_GetStringValue(
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001132 new_annot.get(), pdfium::annotation::kM, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001133 ASSERT_EQ(44u, length_bytes);
1134 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001135 EXPECT_EQ(44u,
1136 FPDFAnnot_GetStringValue(new_annot.get(), pdfium::annotation::kM,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001137 buf.data(), length_bytes));
1138 EXPECT_EQ(kNewDate, GetPlatformWString(buf.data()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001139 }
Jane Liu2e1a32b2017-07-06 12:01:25 -04001140
Henrique Nakashima8baea3c2017-11-10 20:27:23 +00001141 CloseSavedPage(page);
Dan Sinclair04e4dc82017-10-18 12:17:14 -04001142 CloseSavedDocument();
Jane Liu2e1a32b2017-07-06 12:01:25 -04001143}
Diana Gage7e0c05d2017-07-19 17:33:33 -07001144
rycsmith3e785602019-03-05 21:48:36 +00001145TEST_F(FPDFAnnotEmbedderTest, GetNumberValue) {
1146 // Open a file with three text annotations and load its first page.
1147 ASSERT_TRUE(OpenDocument("text_form_multiple.pdf"));
1148 FPDF_PAGE page = LoadPage(0);
1149 ASSERT_TRUE(page);
1150 {
1151 // First two annotations do not have "MaxLen" attribute.
1152 for (int i = 0; i < 2; i++) {
1153 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, i));
1154 ASSERT_TRUE(annot);
1155
1156 // Verify that no "MaxLen" key present.
1157 EXPECT_FALSE(FPDFAnnot_HasKey(annot.get(), "MaxLen"));
1158
1159 float value;
1160 EXPECT_FALSE(FPDFAnnot_GetNumberValue(annot.get(), "MaxLen", &value));
1161 }
1162
1163 // Annotation in index 2 has "MaxLen" of 10.
1164 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
1165 ASSERT_TRUE(annot);
1166
1167 // Verify that "MaxLen" key present.
1168 EXPECT_TRUE(FPDFAnnot_HasKey(annot.get(), "MaxLen"));
1169
1170 float value;
1171 EXPECT_TRUE(FPDFAnnot_GetNumberValue(annot.get(), "MaxLen", &value));
1172 EXPECT_FLOAT_EQ(10.0f, value);
1173
1174 // Check bad inputs.
1175 EXPECT_FALSE(FPDFAnnot_GetNumberValue(nullptr, "MaxLen", &value));
1176 EXPECT_FALSE(FPDFAnnot_GetNumberValue(annot.get(), nullptr, &value));
1177 EXPECT_FALSE(FPDFAnnot_GetNumberValue(annot.get(), "MaxLen", nullptr));
1178 // Ask for key that exists but is not a number.
1179 EXPECT_FALSE(FPDFAnnot_GetNumberValue(annot.get(), "V", &value));
1180 }
1181
1182 UnloadPage(page);
1183}
1184
Lei Zhangab41f252018-12-23 03:10:50 +00001185TEST_F(FPDFAnnotEmbedderTest, GetSetAP) {
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001186 // Open a file with four annotations and load its first page.
1187 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001188 FPDF_PAGE page = LoadPage(0);
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001189 ASSERT_TRUE(page);
1190
Lei Zhanga21d5932018-02-05 18:28:38 +00001191 {
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001192 static const char kMd5NormalAP[] = "be903df0343fd774fadab9c8900cdf4a";
1193 static constexpr size_t kExpectNormalAPLength = 73970;
1194
Lei Zhanga21d5932018-02-05 18:28:38 +00001195 // Retrieve the first annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001196 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001197 ASSERT_TRUE(annot);
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001198
Lei Zhanga21d5932018-02-05 18:28:38 +00001199 // Check that the string value of an AP returns the expected length.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001200 unsigned long normal_length_bytes = FPDFAnnot_GetAP(
Lei Zhanga21d5932018-02-05 18:28:38 +00001201 annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001202 ASSERT_EQ(kExpectNormalAPLength, normal_length_bytes);
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001203
Lei Zhanga21d5932018-02-05 18:28:38 +00001204 // Check that the string value of an AP is not returned if the buffer is too
1205 // small. The result buffer should be overwritten with an empty string.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001206 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(normal_length_bytes);
1207 // Write in the buffer to verify it's not overwritten.
1208 memcpy(buf.data(), "abcdefgh", 8);
1209 EXPECT_EQ(kExpectNormalAPLength,
Lei Zhanga21d5932018-02-05 18:28:38 +00001210 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001211 buf.data(), normal_length_bytes - 1));
1212 EXPECT_EQ(0, memcmp(buf.data(), "abcdefgh", 8));
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001213
Lei Zhanga21d5932018-02-05 18:28:38 +00001214 // Check that the string value of an AP is returned through a buffer that is
1215 // the right size.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001216 EXPECT_EQ(kExpectNormalAPLength,
Lei Zhanga21d5932018-02-05 18:28:38 +00001217 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001218 buf.data(), normal_length_bytes));
1219 EXPECT_EQ(kMd5NormalAP,
1220 GenerateMD5Base16(reinterpret_cast<uint8_t*>(buf.data()),
1221 normal_length_bytes));
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001222
Lei Zhanga21d5932018-02-05 18:28:38 +00001223 // Check that the string value of an AP is returned through a buffer that is
1224 // larger than necessary.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001225 buf = GetFPDFWideStringBuffer(normal_length_bytes + 2);
1226 EXPECT_EQ(kExpectNormalAPLength,
Lei Zhanga21d5932018-02-05 18:28:38 +00001227 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001228 buf.data(), normal_length_bytes + 2));
1229 EXPECT_EQ(kMd5NormalAP,
1230 GenerateMD5Base16(reinterpret_cast<uint8_t*>(buf.data()),
1231 normal_length_bytes));
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001232
Lei Zhanga21d5932018-02-05 18:28:38 +00001233 // Check that getting an AP for a mode that does not have an AP returns an
1234 // empty string.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001235 unsigned long rollover_length_bytes = FPDFAnnot_GetAP(
Lei Zhanga21d5932018-02-05 18:28:38 +00001236 annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001237 ASSERT_EQ(2u, rollover_length_bytes);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001238
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001239 buf = GetFPDFWideStringBuffer(1000);
Lei Zhanga21d5932018-02-05 18:28:38 +00001240 EXPECT_EQ(2u,
1241 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001242 buf.data(), 1000));
1243 EXPECT_EQ(L"", GetPlatformWString(buf.data()));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001244
Lei Zhanga21d5932018-02-05 18:28:38 +00001245 // Check that setting the AP for an invalid appearance mode fails.
Lei Zhangf0f67682019-04-08 17:03:21 +00001246 ScopedFPDFWideString ap_text = GetFPDFWideString(L"new test ap");
Lei Zhang4f556b82019-04-08 16:32:41 +00001247 EXPECT_FALSE(FPDFAnnot_SetAP(annot.get(), -1, ap_text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001248 EXPECT_FALSE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_COUNT,
Lei Zhang4f556b82019-04-08 16:32:41 +00001249 ap_text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001250 EXPECT_FALSE(FPDFAnnot_SetAP(
Lei Zhang4f556b82019-04-08 16:32:41 +00001251 annot.get(), FPDF_ANNOT_APPEARANCEMODE_COUNT + 1, ap_text.get()));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001252
Lei Zhanga21d5932018-02-05 18:28:38 +00001253 // Set the AP correctly now.
1254 EXPECT_TRUE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang4f556b82019-04-08 16:32:41 +00001255 ap_text.get()));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001256
Lei Zhanga21d5932018-02-05 18:28:38 +00001257 // Check that the new annotation value is equal to the value we just set.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001258 rollover_length_bytes = FPDFAnnot_GetAP(
Lei Zhanga21d5932018-02-05 18:28:38 +00001259 annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001260 ASSERT_EQ(24u, rollover_length_bytes);
1261 buf = GetFPDFWideStringBuffer(rollover_length_bytes);
Lei Zhanga21d5932018-02-05 18:28:38 +00001262 EXPECT_EQ(24u,
1263 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001264 buf.data(), rollover_length_bytes));
1265 EXPECT_EQ(L"new test ap", GetPlatformWString(buf.data()));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001266
Lei Zhanga21d5932018-02-05 18:28:38 +00001267 // Check that the Normal AP was not touched when the Rollover AP was set.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001268 buf = GetFPDFWideStringBuffer(normal_length_bytes);
1269 EXPECT_EQ(kExpectNormalAPLength,
Lei Zhanga21d5932018-02-05 18:28:38 +00001270 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001271 buf.data(), normal_length_bytes));
1272 EXPECT_EQ(kMd5NormalAP,
1273 GenerateMD5Base16(reinterpret_cast<uint8_t*>(buf.data()),
1274 normal_length_bytes));
Lei Zhanga21d5932018-02-05 18:28:38 +00001275 }
Henrique Nakashima5970a472018-01-11 22:40:59 +00001276
1277 // Save the modified document, then reopen it.
Henrique Nakashima5970a472018-01-11 22:40:59 +00001278 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang75c81712018-02-08 17:22:39 +00001279 UnloadPage(page);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001280
Lei Zhang0b494052019-01-31 21:41:15 +00001281 ASSERT_TRUE(OpenSavedDocument());
Henrique Nakashima5970a472018-01-11 22:40:59 +00001282 page = LoadSavedPage(0);
Lei Zhanga21d5932018-02-05 18:28:38 +00001283 {
Tom Sepeze08d2b12018-04-25 18:49:32 +00001284 ScopedFPDFAnnotation new_annot(FPDFPage_GetAnnot(page, 0));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001285
Lei Zhanga21d5932018-02-05 18:28:38 +00001286 // Check that the new annotation value is equal to the value we set before
1287 // saving.
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001288 unsigned long rollover_length_bytes = FPDFAnnot_GetAP(
Lei Zhanga21d5932018-02-05 18:28:38 +00001289 new_annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001290 ASSERT_EQ(24u, rollover_length_bytes);
1291 std::vector<FPDF_WCHAR> buf =
1292 GetFPDFWideStringBuffer(rollover_length_bytes);
Lei Zhanga21d5932018-02-05 18:28:38 +00001293 EXPECT_EQ(24u, FPDFAnnot_GetAP(new_annot.get(),
1294 FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001295 buf.data(), rollover_length_bytes));
1296 EXPECT_EQ(L"new test ap", GetPlatformWString(buf.data()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001297 }
Henrique Nakashima5970a472018-01-11 22:40:59 +00001298
1299 // Close saved document.
Henrique Nakashima5970a472018-01-11 22:40:59 +00001300 CloseSavedPage(page);
1301 CloseSavedDocument();
1302}
1303
Lei Zhangab41f252018-12-23 03:10:50 +00001304TEST_F(FPDFAnnotEmbedderTest, RemoveOptionalAP) {
Henrique Nakashima5970a472018-01-11 22:40:59 +00001305 // Open a file with four annotations and load its first page.
1306 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001307 FPDF_PAGE page = LoadPage(0);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001308 ASSERT_TRUE(page);
1309
Lei Zhanga21d5932018-02-05 18:28:38 +00001310 {
1311 // Retrieve the first annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001312 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001313 ASSERT_TRUE(annot);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001314
Lei Zhanga21d5932018-02-05 18:28:38 +00001315 // Set Down AP. Normal AP is already set.
Lei Zhangf0f67682019-04-08 17:03:21 +00001316 ScopedFPDFWideString ap_text = GetFPDFWideString(L"new test ap");
Lei Zhanga21d5932018-02-05 18:28:38 +00001317 EXPECT_TRUE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
Lei Zhang4f556b82019-04-08 16:32:41 +00001318 ap_text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001319 EXPECT_EQ(73970u,
1320 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
1321 nullptr, 0));
1322 EXPECT_EQ(24u, FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
1323 nullptr, 0));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001324
Lei Zhanga21d5932018-02-05 18:28:38 +00001325 // Check that setting the Down AP to null removes the Down entry but keeps
1326 // Normal intact.
1327 EXPECT_TRUE(
1328 FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN, nullptr));
1329 EXPECT_EQ(73970u,
1330 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
1331 nullptr, 0));
1332 EXPECT_EQ(2u, FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
1333 nullptr, 0));
1334 }
Henrique Nakashima5970a472018-01-11 22:40:59 +00001335
Lei Zhang75c81712018-02-08 17:22:39 +00001336 UnloadPage(page);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001337}
1338
Lei Zhangab41f252018-12-23 03:10:50 +00001339TEST_F(FPDFAnnotEmbedderTest, RemoveRequiredAP) {
Henrique Nakashima5970a472018-01-11 22:40:59 +00001340 // Open a file with four annotations and load its first page.
1341 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001342 FPDF_PAGE page = LoadPage(0);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001343 ASSERT_TRUE(page);
1344
Lei Zhanga21d5932018-02-05 18:28:38 +00001345 {
1346 // Retrieve the first annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001347 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001348 ASSERT_TRUE(annot);
Henrique Nakashima5970a472018-01-11 22:40:59 +00001349
Lei Zhanga21d5932018-02-05 18:28:38 +00001350 // Set Down AP. Normal AP is already set.
Lei Zhangf0f67682019-04-08 17:03:21 +00001351 ScopedFPDFWideString ap_text = GetFPDFWideString(L"new test ap");
Lei Zhanga21d5932018-02-05 18:28:38 +00001352 EXPECT_TRUE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
Lei Zhang4f556b82019-04-08 16:32:41 +00001353 ap_text.get()));
Lei Zhanga21d5932018-02-05 18:28:38 +00001354 EXPECT_EQ(73970u,
1355 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
1356 nullptr, 0));
1357 EXPECT_EQ(24u, FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
1358 nullptr, 0));
Henrique Nakashima5970a472018-01-11 22:40:59 +00001359
Lei Zhanga21d5932018-02-05 18:28:38 +00001360 // Check that setting the Normal AP to null removes the whole AP dictionary.
1361 EXPECT_TRUE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
1362 nullptr));
1363 EXPECT_EQ(2u, FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_NORMAL,
1364 nullptr, 0));
1365 EXPECT_EQ(2u, FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_DOWN,
1366 nullptr, 0));
1367 }
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001368
Lei Zhang75c81712018-02-08 17:22:39 +00001369 UnloadPage(page);
Henrique Nakashimaa74e75d2018-01-10 18:06:55 +00001370}
1371
Lei Zhangab41f252018-12-23 03:10:50 +00001372TEST_F(FPDFAnnotEmbedderTest, ExtractLinkedAnnotations) {
Jane Liu300bb272017-08-21 14:37:53 -04001373 // Open a file with annotations and load its first page.
1374 ASSERT_TRUE(OpenDocument("annotation_highlight_square_with_ap.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001375 FPDF_PAGE page = LoadPage(0);
Jane Liu300bb272017-08-21 14:37:53 -04001376 ASSERT_TRUE(page);
Jane Liud1ed1ce2017-08-24 12:31:10 -04001377 EXPECT_EQ(-1, FPDFPage_GetAnnotIndex(page, nullptr));
Jane Liu300bb272017-08-21 14:37:53 -04001378
Lei Zhanga21d5932018-02-05 18:28:38 +00001379 {
1380 // Retrieve the highlight annotation which has its popup defined.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001381 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001382 ASSERT_TRUE(annot);
1383 EXPECT_EQ(FPDF_ANNOT_HIGHLIGHT, FPDFAnnot_GetSubtype(annot.get()));
1384 EXPECT_EQ(0, FPDFPage_GetAnnotIndex(page, annot.get()));
Lei Zhang4f556b82019-04-08 16:32:41 +00001385 static const char kPopupKey[] = "Popup";
Lei Zhanga21d5932018-02-05 18:28:38 +00001386 ASSERT_TRUE(FPDFAnnot_HasKey(annot.get(), kPopupKey));
1387 ASSERT_EQ(FPDF_OBJECT_REFERENCE,
1388 FPDFAnnot_GetValueType(annot.get(), kPopupKey));
Jane Liu300bb272017-08-21 14:37:53 -04001389
Lei Zhanga21d5932018-02-05 18:28:38 +00001390 // Retrieve and verify the popup of the highlight annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001391 ScopedFPDFAnnotation popup(
Lei Zhanga21d5932018-02-05 18:28:38 +00001392 FPDFAnnot_GetLinkedAnnot(annot.get(), kPopupKey));
1393 ASSERT_TRUE(popup);
1394 EXPECT_EQ(FPDF_ANNOT_POPUP, FPDFAnnot_GetSubtype(popup.get()));
1395 EXPECT_EQ(1, FPDFPage_GetAnnotIndex(page, popup.get()));
1396 FS_RECTF rect;
1397 ASSERT_TRUE(FPDFAnnot_GetRect(popup.get(), &rect));
1398 EXPECT_NEAR(612.0f, rect.left, 0.001f);
1399 EXPECT_NEAR(578.792, rect.bottom, 0.001f);
Jane Liu300bb272017-08-21 14:37:53 -04001400
Lei Zhanga21d5932018-02-05 18:28:38 +00001401 // Attempting to retrieve |annot|'s "IRT"-linked annotation would fail,
1402 // since "IRT" is not a key in |annot|'s dictionary.
Lei Zhang4f556b82019-04-08 16:32:41 +00001403 static const char kIRTKey[] = "IRT";
Lei Zhanga21d5932018-02-05 18:28:38 +00001404 ASSERT_FALSE(FPDFAnnot_HasKey(annot.get(), kIRTKey));
1405 EXPECT_FALSE(FPDFAnnot_GetLinkedAnnot(annot.get(), kIRTKey));
Jane Liu300bb272017-08-21 14:37:53 -04001406
Lei Zhanga21d5932018-02-05 18:28:38 +00001407 // Attempting to retrieve |annot|'s parent dictionary as an annotation
1408 // would fail, since its parent is not an annotation.
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001409 ASSERT_TRUE(FPDFAnnot_HasKey(annot.get(), pdfium::annotation::kP));
Lei Zhanga21d5932018-02-05 18:28:38 +00001410 EXPECT_EQ(FPDF_OBJECT_REFERENCE,
Lei Zhanga5c1daf2019-01-31 21:56:47 +00001411 FPDFAnnot_GetValueType(annot.get(), pdfium::annotation::kP));
1412 EXPECT_FALSE(FPDFAnnot_GetLinkedAnnot(annot.get(), pdfium::annotation::kP));
Lei Zhanga21d5932018-02-05 18:28:38 +00001413 }
Jane Liu300bb272017-08-21 14:37:53 -04001414
Jane Liu300bb272017-08-21 14:37:53 -04001415 UnloadPage(page);
1416}
1417
Lei Zhangab41f252018-12-23 03:10:50 +00001418TEST_F(FPDFAnnotEmbedderTest, GetFormFieldFlagsTextField) {
Diana Gage7e0c05d2017-07-19 17:33:33 -07001419 // Open file with form text fields.
1420 ASSERT_TRUE(OpenDocument("text_form_multiple.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001421 FPDF_PAGE page = LoadPage(0);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001422 ASSERT_TRUE(page);
1423
Lei Zhanga21d5932018-02-05 18:28:38 +00001424 {
1425 // Retrieve the first annotation: user-editable text field.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001426 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001427 ASSERT_TRUE(annot);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001428
Lei Zhanga21d5932018-02-05 18:28:38 +00001429 // Check that the flag values are as expected.
Lei Zhange6fcdfa2019-02-14 04:07:09 +00001430 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), page, annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001431 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1432 }
Diana Gage7e0c05d2017-07-19 17:33:33 -07001433
Lei Zhanga21d5932018-02-05 18:28:38 +00001434 {
1435 // Retrieve the second annotation: read-only text field.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001436 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 1));
Lei Zhanga21d5932018-02-05 18:28:38 +00001437 ASSERT_TRUE(annot);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001438
Lei Zhanga21d5932018-02-05 18:28:38 +00001439 // Check that the flag values are as expected.
Lei Zhange6fcdfa2019-02-14 04:07:09 +00001440 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), page, annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001441 EXPECT_TRUE(flags & FPDF_FORMFLAG_READONLY);
1442 }
Diana Gage7e0c05d2017-07-19 17:33:33 -07001443
1444 UnloadPage(page);
1445}
1446
Lei Zhangab41f252018-12-23 03:10:50 +00001447TEST_F(FPDFAnnotEmbedderTest, GetFormFieldFlagsComboBox) {
Diana Gage7e0c05d2017-07-19 17:33:33 -07001448 // Open file with form text fields.
1449 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
Lei Zhang75c81712018-02-08 17:22:39 +00001450 FPDF_PAGE page = LoadPage(0);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001451 ASSERT_TRUE(page);
1452
Lei Zhanga21d5932018-02-05 18:28:38 +00001453 {
1454 // Retrieve the first annotation: user-editable combobox.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001455 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
Lei Zhanga21d5932018-02-05 18:28:38 +00001456 ASSERT_TRUE(annot);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001457
Lei Zhanga21d5932018-02-05 18:28:38 +00001458 // Check that the flag values are as expected.
Lei Zhange6fcdfa2019-02-14 04:07:09 +00001459 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), page, annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001460 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1461 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1462 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1463 }
Diana Gage7e0c05d2017-07-19 17:33:33 -07001464
Lei Zhanga21d5932018-02-05 18:28:38 +00001465 {
1466 // Retrieve the second annotation: regular combobox.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001467 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 1));
Lei Zhanga21d5932018-02-05 18:28:38 +00001468 ASSERT_TRUE(annot);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001469
Lei Zhanga21d5932018-02-05 18:28:38 +00001470 // Check that the flag values are as expected.
Lei Zhange6fcdfa2019-02-14 04:07:09 +00001471 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), page, annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001472 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1473 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1474 EXPECT_FALSE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1475 }
Diana Gage7e0c05d2017-07-19 17:33:33 -07001476
Lei Zhanga21d5932018-02-05 18:28:38 +00001477 {
1478 // Retrieve the third annotation: read-only combobox.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001479 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2));
Lei Zhanga21d5932018-02-05 18:28:38 +00001480 ASSERT_TRUE(annot);
Diana Gage7e0c05d2017-07-19 17:33:33 -07001481
Lei Zhanga21d5932018-02-05 18:28:38 +00001482 // Check that the flag values are as expected.
Lei Zhange6fcdfa2019-02-14 04:07:09 +00001483 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), page, annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001484 EXPECT_TRUE(flags & FPDF_FORMFLAG_READONLY);
1485 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1486 EXPECT_FALSE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1487 }
Diana Gage7e0c05d2017-07-19 17:33:33 -07001488
1489 UnloadPage(page);
1490}
Diana Gage40870db2017-07-19 18:16:03 -07001491
Lei Zhangab41f252018-12-23 03:10:50 +00001492TEST_F(FPDFAnnotEmbedderTest, GetFormAnnotNull) {
Diana Gage40870db2017-07-19 18:16:03 -07001493 // Open file with form text fields.
1494 EXPECT_TRUE(OpenDocument("text_form.pdf"));
1495 FPDF_PAGE page = LoadPage(0);
1496 ASSERT_TRUE(page);
1497
1498 // Attempt to get an annotation where no annotation exists on page.
Lei Zhang7557e7b2018-09-14 17:02:40 +00001499 EXPECT_FALSE(FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 0, 0));
1500
1501 {
1502 // Verify there is an annotation.
1503 ScopedFPDFAnnotation annot(
1504 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 120, 120));
1505 EXPECT_TRUE(annot);
1506 }
1507
1508 // Try other bad inputs at a valid location.
1509 EXPECT_FALSE(FPDFAnnot_GetFormFieldAtPoint(nullptr, nullptr, 120, 120));
1510 EXPECT_FALSE(FPDFAnnot_GetFormFieldAtPoint(nullptr, page, 120, 120));
1511 EXPECT_FALSE(FPDFAnnot_GetFormFieldAtPoint(form_handle(), nullptr, 120, 120));
Diana Gage40870db2017-07-19 18:16:03 -07001512
1513 UnloadPage(page);
1514}
1515
Lei Zhangab41f252018-12-23 03:10:50 +00001516TEST_F(FPDFAnnotEmbedderTest, GetFormAnnotAndCheckFlagsTextField) {
Diana Gage40870db2017-07-19 18:16:03 -07001517 // Open file with form text fields.
1518 EXPECT_TRUE(OpenDocument("text_form_multiple.pdf"));
1519 FPDF_PAGE page = LoadPage(0);
1520 ASSERT_TRUE(page);
1521
Lei Zhanga21d5932018-02-05 18:28:38 +00001522 {
1523 // Retrieve user-editable text field annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001524 ScopedFPDFAnnotation annot(
Lei Zhanga21d5932018-02-05 18:28:38 +00001525 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 105, 118));
1526 ASSERT_TRUE(annot);
Diana Gage40870db2017-07-19 18:16:03 -07001527
Lei Zhanga21d5932018-02-05 18:28:38 +00001528 // Check that interactive form annotation flag values are as expected.
Lei Zhange6fcdfa2019-02-14 04:07:09 +00001529 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), page, annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001530 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1531 }
Diana Gage40870db2017-07-19 18:16:03 -07001532
Lei Zhanga21d5932018-02-05 18:28:38 +00001533 {
1534 // Retrieve read-only text field annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001535 ScopedFPDFAnnotation annot(
Lei Zhanga21d5932018-02-05 18:28:38 +00001536 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 105, 202));
1537 ASSERT_TRUE(annot);
Diana Gage40870db2017-07-19 18:16:03 -07001538
Lei Zhanga21d5932018-02-05 18:28:38 +00001539 // Check that interactive form annotation flag values are as expected.
Lei Zhange6fcdfa2019-02-14 04:07:09 +00001540 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), page, annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001541 EXPECT_TRUE(flags & FPDF_FORMFLAG_READONLY);
1542 }
Diana Gage40870db2017-07-19 18:16:03 -07001543
1544 UnloadPage(page);
1545}
1546
Lei Zhangab41f252018-12-23 03:10:50 +00001547TEST_F(FPDFAnnotEmbedderTest, GetFormAnnotAndCheckFlagsComboBox) {
Diana Gage40870db2017-07-19 18:16:03 -07001548 // Open file with form comboboxes.
1549 EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
1550 FPDF_PAGE page = LoadPage(0);
1551 ASSERT_TRUE(page);
1552
Lei Zhanga21d5932018-02-05 18:28:38 +00001553 {
1554 // Retrieve user-editable combobox annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001555 ScopedFPDFAnnotation annot(
Henrique Nakashima20830922018-03-19 21:21:46 +00001556 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 102, 363));
Lei Zhanga21d5932018-02-05 18:28:38 +00001557 ASSERT_TRUE(annot);
Diana Gage40870db2017-07-19 18:16:03 -07001558
Lei Zhanga21d5932018-02-05 18:28:38 +00001559 // Check that interactive form annotation flag values are as expected.
Lei Zhange6fcdfa2019-02-14 04:07:09 +00001560 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), page, annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001561 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1562 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1563 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1564 }
Diana Gage40870db2017-07-19 18:16:03 -07001565
Lei Zhanga21d5932018-02-05 18:28:38 +00001566 {
1567 // Retrieve regular combobox annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001568 ScopedFPDFAnnotation annot(
Henrique Nakashima20830922018-03-19 21:21:46 +00001569 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 102, 413));
Lei Zhanga21d5932018-02-05 18:28:38 +00001570 ASSERT_TRUE(annot);
Diana Gage40870db2017-07-19 18:16:03 -07001571
Lei Zhanga21d5932018-02-05 18:28:38 +00001572 // Check that interactive form annotation flag values are as expected.
Lei Zhange6fcdfa2019-02-14 04:07:09 +00001573 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), page, annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001574 EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
1575 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1576 EXPECT_FALSE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1577 }
Diana Gage40870db2017-07-19 18:16:03 -07001578
Lei Zhanga21d5932018-02-05 18:28:38 +00001579 {
1580 // Retrieve read-only combobox annotation.
Tom Sepeze08d2b12018-04-25 18:49:32 +00001581 ScopedFPDFAnnotation annot(
Henrique Nakashima20830922018-03-19 21:21:46 +00001582 FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 102, 513));
Lei Zhanga21d5932018-02-05 18:28:38 +00001583 ASSERT_TRUE(annot);
Diana Gage40870db2017-07-19 18:16:03 -07001584
Lei Zhanga21d5932018-02-05 18:28:38 +00001585 // Check that interactive form annotation flag values are as expected.
Lei Zhange6fcdfa2019-02-14 04:07:09 +00001586 int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), page, annot.get());
Lei Zhanga21d5932018-02-05 18:28:38 +00001587 EXPECT_TRUE(flags & FPDF_FORMFLAG_READONLY);
1588 EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO);
1589 EXPECT_FALSE(flags & FPDF_FORMFLAG_CHOICE_EDIT);
1590 }
Diana Gage40870db2017-07-19 18:16:03 -07001591
1592 UnloadPage(page);
1593}
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001594
Lei Zhang992e7e22019-02-04 19:20:58 +00001595TEST_F(FPDFAnnotEmbedderTest, BUG_1206) {
1596 static constexpr size_t kExpectedSize = 1609;
1597 static const char kExpectedBitmap[] = "0d9fc05c6762fd788bd23fd87a4967bc";
1598
1599 ASSERT_TRUE(OpenDocument("bug_1206.pdf"));
1600
1601 FPDF_PAGE page = LoadPage(0);
1602 ASSERT_TRUE(page);
1603
1604 ASSERT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
1605 EXPECT_EQ(kExpectedSize, GetString().size());
1606 ClearString();
1607
1608 for (size_t i = 0; i < 10; ++i) {
1609 ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT);
1610 CompareBitmap(bitmap.get(), 612, 792, kExpectedBitmap);
1611
1612 ASSERT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
1613 // TODO(https://crbug.com/pdfium/1206): This is wrong. The size should be
1614 // equal, not bigger.
1615 EXPECT_LT(kExpectedSize, GetString().size());
1616 ClearString();
1617 }
1618
1619 UnloadPage(page);
1620}
1621
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001622TEST_F(FPDFAnnotEmbedderTest, BUG_1212) {
1623 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
1624 FPDF_PAGE page = LoadPage(0);
1625 ASSERT_TRUE(page);
1626 EXPECT_EQ(0, FPDFPage_GetAnnotCount(page));
1627
1628 static const char kTestKey[] = "test";
Lei Zhang4f556b82019-04-08 16:32:41 +00001629 static const wchar_t kData[] = L"\xf6\xe4";
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001630 static const size_t kBufSize = 12;
1631 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(kBufSize);
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001632
1633 {
1634 // Add a text annotation to the page.
1635 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_TEXT));
1636 ASSERT_TRUE(annot);
1637 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
1638 EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
1639
1640 // Make sure there is no test key, add set a value there, and read it back.
1641 std::fill(buf.begin(), buf.end(), 'x');
1642 ASSERT_EQ(2u, FPDFAnnot_GetStringValue(annot.get(), kTestKey, buf.data(),
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001643 kBufSize));
1644 EXPECT_EQ(L"", GetPlatformWString(buf.data()));
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001645
Lei Zhangf0f67682019-04-08 17:03:21 +00001646 ScopedFPDFWideString text = GetFPDFWideString(kData);
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001647 EXPECT_TRUE(FPDFAnnot_SetStringValue(annot.get(), kTestKey, text.get()));
1648
1649 std::fill(buf.begin(), buf.end(), 'x');
1650 ASSERT_EQ(6u, FPDFAnnot_GetStringValue(annot.get(), kTestKey, buf.data(),
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001651 kBufSize));
1652 EXPECT_EQ(kData, GetPlatformWString(buf.data()));
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001653 }
1654
Lei Zhang05ec64c2019-01-09 03:00:06 +00001655 {
1656 ScopedFPDFAnnotation annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP));
1657 ASSERT_TRUE(annot);
1658 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
1659 EXPECT_EQ(FPDF_ANNOT_STAMP, FPDFAnnot_GetSubtype(annot.get()));
1660 // Also do the same test for its appearance string.
1661 std::fill(buf.begin(), buf.end(), 'x');
1662 ASSERT_EQ(2u,
1663 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001664 buf.data(), kBufSize));
1665 EXPECT_EQ(L"", GetPlatformWString(buf.data()));
Lei Zhang05ec64c2019-01-09 03:00:06 +00001666
Lei Zhangf0f67682019-04-08 17:03:21 +00001667 ScopedFPDFWideString text = GetFPDFWideString(kData);
Lei Zhang05ec64c2019-01-09 03:00:06 +00001668 EXPECT_TRUE(FPDFAnnot_SetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
1669 text.get()));
1670
1671 std::fill(buf.begin(), buf.end(), 'x');
1672 ASSERT_EQ(6u,
1673 FPDFAnnot_GetAP(annot.get(), FPDF_ANNOT_APPEARANCEMODE_ROLLOVER,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001674 buf.data(), kBufSize));
1675 EXPECT_EQ(kData, GetPlatformWString(buf.data()));
Lei Zhang05ec64c2019-01-09 03:00:06 +00001676 }
1677
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001678 UnloadPage(page);
1679
1680 {
1681 // Save a copy, open the copy, and check the annotation again.
1682 // Note that it renders the rotation.
1683 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
Lei Zhang0b494052019-01-31 21:41:15 +00001684 ASSERT_TRUE(OpenSavedDocument());
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001685 FPDF_PAGE saved_page = LoadSavedPage(0);
1686 ASSERT_TRUE(saved_page);
1687
Lei Zhang05ec64c2019-01-09 03:00:06 +00001688 EXPECT_EQ(2, FPDFPage_GetAnnotCount(saved_page));
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001689 {
1690 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(saved_page, 0));
1691 ASSERT_TRUE(annot);
1692 EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
1693
1694 std::fill(buf.begin(), buf.end(), 'x');
1695 ASSERT_EQ(6u, FPDFAnnot_GetStringValue(annot.get(), kTestKey, buf.data(),
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001696 kBufSize));
1697 EXPECT_EQ(kData, GetPlatformWString(buf.data()));
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001698 }
1699
Lei Zhang05ec64c2019-01-09 03:00:06 +00001700 {
1701 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(saved_page, 0));
1702 ASSERT_TRUE(annot);
1703 // TODO(thestig): This return FPDF_ANNOT_UNKNOWN for some reason.
1704 // EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot.get()));
1705
1706 std::fill(buf.begin(), buf.end(), 'x');
1707 ASSERT_EQ(6u, FPDFAnnot_GetStringValue(annot.get(), kTestKey, buf.data(),
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001708 kBufSize));
1709 EXPECT_EQ(kData, GetPlatformWString(buf.data()));
Lei Zhang05ec64c2019-01-09 03:00:06 +00001710 }
1711
Lei Zhangf5fcd9e2018-12-23 03:11:50 +00001712 CloseSavedPage(saved_page);
1713 CloseSavedDocument();
1714 }
1715}
rycsmithcb752f32019-02-21 18:40:53 +00001716
1717TEST_F(FPDFAnnotEmbedderTest, GetOptionCountCombobox) {
1718 // Open a file with combobox widget annotations and load its first page.
1719 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
1720 FPDF_PAGE page = LoadPage(0);
1721 ASSERT_TRUE(page);
1722
1723 {
1724 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1725 ASSERT_TRUE(annot);
1726
1727 EXPECT_EQ(3, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
1728
1729 annot.reset(FPDFPage_GetAnnot(page, 1));
1730 ASSERT_TRUE(annot);
1731
1732 EXPECT_EQ(26, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
Lei Zhange7033c82019-02-26 19:30:49 +00001733
1734 // Check bad form handle / annot.
1735 EXPECT_EQ(-1, FPDFAnnot_GetOptionCount(nullptr, nullptr));
1736 EXPECT_EQ(-1, FPDFAnnot_GetOptionCount(form_handle(), nullptr));
1737 EXPECT_EQ(-1, FPDFAnnot_GetOptionCount(nullptr, annot.get()));
rycsmithcb752f32019-02-21 18:40:53 +00001738 }
1739
1740 UnloadPage(page);
1741}
1742
1743TEST_F(FPDFAnnotEmbedderTest, GetOptionCountListbox) {
1744 // Open a file with listbox widget annotations and load its first page.
1745 ASSERT_TRUE(OpenDocument("listbox_form.pdf"));
1746 FPDF_PAGE page = LoadPage(0);
1747 ASSERT_TRUE(page);
1748
1749 {
1750 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1751 ASSERT_TRUE(annot);
1752
1753 EXPECT_EQ(3, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
1754
1755 annot.reset(FPDFPage_GetAnnot(page, 1));
1756 ASSERT_TRUE(annot);
1757
1758 EXPECT_EQ(26, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
1759 }
1760
1761 UnloadPage(page);
1762}
1763
1764TEST_F(FPDFAnnotEmbedderTest, GetOptionCountInvalidAnnotations) {
1765 // Open a file with ink annotations and load its first page.
1766 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
1767 FPDF_PAGE page = LoadPage(0);
1768 ASSERT_TRUE(page);
1769
1770 {
1771 // annotations do not have "Opt" array and will return -1
1772 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1773 ASSERT_TRUE(annot);
1774
1775 EXPECT_EQ(-1, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
1776
1777 annot.reset(FPDFPage_GetAnnot(page, 1));
1778 ASSERT_TRUE(annot);
1779
1780 EXPECT_EQ(-1, FPDFAnnot_GetOptionCount(form_handle(), annot.get()));
1781 }
1782
1783 UnloadPage(page);
1784}
1785
1786TEST_F(FPDFAnnotEmbedderTest, GetOptionLabelCombobox) {
1787 // Open a file with combobox widget annotations and load its first page.
1788 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
1789 FPDF_PAGE page = LoadPage(0);
1790 ASSERT_TRUE(page);
1791
1792 {
1793 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1794 ASSERT_TRUE(annot);
1795
1796 int index = 0;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001797 unsigned long length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001798 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001799 ASSERT_EQ(8u, length_bytes);
1800 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001801 EXPECT_EQ(8u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001802 buf.data(), length_bytes));
1803 EXPECT_EQ(L"Foo", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001804
1805 annot.reset(FPDFPage_GetAnnot(page, 1));
1806 ASSERT_TRUE(annot);
1807
1808 index = 0;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001809 length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001810 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001811 ASSERT_EQ(12u, length_bytes);
1812 buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001813 EXPECT_EQ(12u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001814 buf.data(), length_bytes));
1815 EXPECT_EQ(L"Apple", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001816
1817 index = 25;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001818 length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001819 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001820 buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001821 EXPECT_EQ(18u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001822 buf.data(), length_bytes));
1823 EXPECT_EQ(L"Zucchini", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001824
Lei Zhange7033c82019-02-26 19:30:49 +00001825 // Indices out of range
rycsmithcb752f32019-02-21 18:40:53 +00001826 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), -1,
1827 nullptr, 0));
1828 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), 26,
1829 nullptr, 0));
Lei Zhange7033c82019-02-26 19:30:49 +00001830
1831 // Check bad form handle / annot.
1832 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(nullptr, nullptr, 0, nullptr, 0));
1833 EXPECT_EQ(0u,
1834 FPDFAnnot_GetOptionLabel(nullptr, annot.get(), 0, nullptr, 0));
1835 EXPECT_EQ(0u,
1836 FPDFAnnot_GetOptionLabel(form_handle(), nullptr, 0, nullptr, 0));
rycsmithcb752f32019-02-21 18:40:53 +00001837 }
1838
1839 UnloadPage(page);
1840}
1841
1842TEST_F(FPDFAnnotEmbedderTest, GetOptionLabelListbox) {
1843 // Open a file with listbox widget annotations and load its first page.
1844 ASSERT_TRUE(OpenDocument("listbox_form.pdf"));
1845 FPDF_PAGE page = LoadPage(0);
1846 ASSERT_TRUE(page);
1847
1848 {
1849 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1850 ASSERT_TRUE(annot);
1851
1852 int index = 0;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001853 unsigned long length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001854 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001855 ASSERT_EQ(8u, length_bytes);
1856 std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001857 EXPECT_EQ(8u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001858 buf.data(), length_bytes));
1859 EXPECT_EQ(L"Foo", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001860
1861 annot.reset(FPDFPage_GetAnnot(page, 1));
1862 ASSERT_TRUE(annot);
1863
1864 index = 0;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001865 length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001866 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001867 ASSERT_EQ(12u, length_bytes);
1868 buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001869 EXPECT_EQ(12u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001870 buf.data(), length_bytes));
1871 EXPECT_EQ(L"Apple", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001872
1873 index = 25;
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001874 length_bytes =
rycsmithcb752f32019-02-21 18:40:53 +00001875 FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index, nullptr, 0);
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001876 ASSERT_EQ(18u, length_bytes);
1877 buf = GetFPDFWideStringBuffer(length_bytes);
rycsmithcb752f32019-02-21 18:40:53 +00001878 EXPECT_EQ(18u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), index,
Lei Zhang5bf8c7f2019-04-08 17:50:11 +00001879 buf.data(), length_bytes));
1880 EXPECT_EQ(L"Zucchini", GetPlatformWString(buf.data()));
rycsmithcb752f32019-02-21 18:40:53 +00001881
1882 // indices out of range
1883 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), -1,
1884 nullptr, 0));
1885 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), 26,
1886 nullptr, 0));
1887 }
1888
1889 UnloadPage(page);
1890}
1891
1892TEST_F(FPDFAnnotEmbedderTest, GetOptionLabelInvalidAnnotations) {
1893 // Open a file with ink annotations and load its first page.
1894 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
1895 FPDF_PAGE page = LoadPage(0);
1896 ASSERT_TRUE(page);
1897
1898 {
1899 // annotations do not have "Opt" array and will return 0
1900 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1901 ASSERT_TRUE(annot);
1902
1903 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), 0,
1904 nullptr, 0));
1905
1906 annot.reset(FPDFPage_GetAnnot(page, 1));
1907 ASSERT_TRUE(annot);
1908
1909 EXPECT_EQ(0u, FPDFAnnot_GetOptionLabel(form_handle(), annot.get(), 0,
1910 nullptr, 0));
1911 }
1912
1913 UnloadPage(page);
1914}
Ryan Smith09c23b12019-04-25 18:09:06 +00001915
1916TEST_F(FPDFAnnotEmbedderTest, GetFontSizeCombobox) {
1917 // Open a file with combobox annotations and load its first page.
1918 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
1919 FPDF_PAGE page = LoadPage(0);
1920 ASSERT_TRUE(page);
1921
1922 {
1923 // All 3 widgets have Tf font size 12.
1924 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1925 ASSERT_TRUE(annot);
1926
1927 float value;
1928 ASSERT_TRUE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value));
1929 EXPECT_EQ(12.0, value);
1930
1931 annot.reset(FPDFPage_GetAnnot(page, 1));
1932 ASSERT_TRUE(annot);
1933
1934 float value_two;
1935 ASSERT_TRUE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value_two));
1936 EXPECT_EQ(12.0, value_two);
1937
1938 annot.reset(FPDFPage_GetAnnot(page, 2));
1939 ASSERT_TRUE(annot);
1940
1941 float value_three;
1942 ASSERT_TRUE(
1943 FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value_three));
1944 EXPECT_EQ(12.0, value_three);
1945 }
1946
1947 UnloadPage(page);
1948}
1949
1950TEST_F(FPDFAnnotEmbedderTest, GetFontSizeTextField) {
1951 // Open a file with textfield annotations and load its first page.
1952 ASSERT_TRUE(OpenDocument("text_form_multiple.pdf"));
1953 FPDF_PAGE page = LoadPage(0);
1954 ASSERT_TRUE(page);
1955
1956 {
1957 // All 3 widgets have Tf font size 12.
1958 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1959 ASSERT_TRUE(annot);
1960
1961 float value;
1962 ASSERT_TRUE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value));
1963 EXPECT_EQ(12.0, value);
1964
1965 annot.reset(FPDFPage_GetAnnot(page, 1));
1966 ASSERT_TRUE(annot);
1967
1968 float value_two;
1969 ASSERT_TRUE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value_two));
1970 EXPECT_EQ(12.0, value_two);
1971
1972 annot.reset(FPDFPage_GetAnnot(page, 2));
1973 ASSERT_TRUE(annot);
1974
1975 float value_three;
1976 ASSERT_TRUE(
1977 FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value_three));
1978 EXPECT_EQ(12.0, value_three);
1979 }
1980
1981 UnloadPage(page);
1982}
1983
1984TEST_F(FPDFAnnotEmbedderTest, GetFontSizeInvalidAnnotationTypes) {
1985 // Open a file with ink annotations and load its first page.
1986 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
1987 FPDF_PAGE page = LoadPage(0);
1988 ASSERT_TRUE(page);
1989
1990 {
1991 // Annotations that do not have variable text and will return -1.
1992 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
1993 ASSERT_TRUE(annot);
1994
1995 float value;
1996 ASSERT_FALSE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value));
1997
1998 annot.reset(FPDFPage_GetAnnot(page, 1));
1999 ASSERT_TRUE(annot);
2000
2001 ASSERT_FALSE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value));
2002 }
2003
2004 UnloadPage(page);
2005}
2006
2007TEST_F(FPDFAnnotEmbedderTest, GetFontSizeInvalidArguments) {
2008 // Open a file with combobox annotations and load its first page.
2009 ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
2010 FPDF_PAGE page = LoadPage(0);
2011 ASSERT_TRUE(page);
2012
2013 {
2014 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2015 ASSERT_TRUE(annot);
2016
2017 // Check bad form handle / annot.
2018 float value;
2019 ASSERT_FALSE(FPDFAnnot_GetFontSize(nullptr, annot.get(), &value));
2020 ASSERT_FALSE(FPDFAnnot_GetFontSize(form_handle(), nullptr, &value));
2021 ASSERT_FALSE(FPDFAnnot_GetFontSize(nullptr, nullptr, &value));
2022 }
2023
2024 UnloadPage(page);
2025}
2026
2027TEST_F(FPDFAnnotEmbedderTest, GetFontSizeNegative) {
2028 // Open a file with textfield annotations and load its first page.
2029 ASSERT_TRUE(OpenDocument("text_form_negative_fontsize.pdf"));
2030 FPDF_PAGE page = LoadPage(0);
2031 ASSERT_TRUE(page);
2032
2033 {
2034 // Obtain the first annotation, a text field with negative font size, -12.
2035 ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
2036 ASSERT_TRUE(annot);
2037
2038 float value;
2039 ASSERT_TRUE(FPDFAnnot_GetFontSize(form_handle(), annot.get(), &value));
2040 EXPECT_EQ(-12.0, value);
2041 }
2042
2043 UnloadPage(page);
2044}