blob: e62d7c5d4565f49dbf25e69802afba86d5d58302 [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
Jane Liu20eafda2017-06-07 10:33:24 -04005#include <memory>
6#include <string>
Jane Liu4fd9a472017-06-01 18:56:09 -04007#include <vector>
8
Jane Liubaa7ff42017-06-29 19:18:23 -04009#include "core/fxcrt/fx_system.h"
Jane Liu4fd9a472017-06-01 18:56:09 -040010#include "public/fpdf_annot.h"
Jane Liubaa7ff42017-06-29 19:18:23 -040011#include "public/fpdf_edit.h"
Jane Liu4fd9a472017-06-01 18:56:09 -040012#include "public/fpdfview.h"
13#include "testing/embedder_test.h"
14#include "testing/gtest/include/gtest/gtest.h"
15
Nicolas Pena3ff54002017-07-05 11:55:35 -040016class FPDFAnnotEmbeddertest : public EmbedderTest {};
Jane Liu4fd9a472017-06-01 18:56:09 -040017
Jane Liue17011d2017-06-21 12:18:37 -040018TEST_F(FPDFAnnotEmbeddertest, RenderAnnotWithOnlyRolloverAP) {
19 // Open a file with one annotation and load its first page.
20 ASSERT_TRUE(OpenDocument("annotation_highlight_rollover_ap.pdf"));
21 FPDF_PAGE page = FPDF_LoadPage(document(), 0);
22 ASSERT_TRUE(page);
23
24 // This annotation has a malformed appearance stream, which does not have its
25 // normal appearance defined, only its rollover appearance. In this case, its
26 // normal appearance should be generated, allowing the highlight annotation to
27 // still display.
Nicolas Pena3ff54002017-07-05 11:55:35 -040028 FPDF_BITMAP bitmap = RenderPageWithFlags(page, form_handle(), FPDF_ANNOT);
Jane Liue17011d2017-06-21 12:18:37 -040029 CompareBitmap(bitmap, 612, 792, "dc98f06da047bd8aabfa99562d2cbd1e");
30 FPDFBitmap_Destroy(bitmap);
31
32 UnloadPage(page);
33}
34
Jane Liu4fd9a472017-06-01 18:56:09 -040035TEST_F(FPDFAnnotEmbeddertest, ExtractHighlightLongContent) {
36 // Open a file with one annotation and load its first page.
37 ASSERT_TRUE(OpenDocument("annotation_highlight_long_content.pdf"));
38 FPDF_PAGE page = FPDF_LoadPage(document(), 0);
39 ASSERT_TRUE(page);
40
41 // Check that there is a total of 1 annotation on its first page.
42 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
43
44 // Check that the annotation is of type "highlight".
Jane Liud60e9ad2017-06-26 11:28:36 -040045 FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 0);
46 ASSERT_TRUE(annot);
Jane Liu4fd9a472017-06-01 18:56:09 -040047 EXPECT_EQ(FPDF_ANNOT_HIGHLIGHT, FPDFAnnot_GetSubtype(annot));
48
49 // Check that the annotation color is yellow.
50 unsigned int R;
51 unsigned int G;
52 unsigned int B;
53 unsigned int A;
54 EXPECT_TRUE(
55 FPDFAnnot_GetColor(annot, FPDFANNOT_COLORTYPE_Color, &R, &G, &B, &A));
56 EXPECT_EQ(255u, R);
57 EXPECT_EQ(255u, G);
58 EXPECT_EQ(0u, B);
59 EXPECT_EQ(255u, A);
60
61 // Check that the author is correct.
Jane Liu2e1a32b2017-07-06 12:01:25 -040062 std::unique_ptr<unsigned short, pdfium::FreeDeleter> author_key =
63 GetFPDFWideString(L"T");
64 EXPECT_EQ(FPDF_OBJECT_STRING,
65 FPDFAnnot_GetValueType(annot, author_key.get()));
Jane Liu4fd9a472017-06-01 18:56:09 -040066 unsigned long len =
Jane Liu2e1a32b2017-07-06 12:01:25 -040067 FPDFAnnot_GetStringValue(annot, author_key.get(), nullptr, 0);
Jane Liu4fd9a472017-06-01 18:56:09 -040068 std::vector<char> buf(len);
Jane Liu2e1a32b2017-07-06 12:01:25 -040069 EXPECT_EQ(28u,
70 FPDFAnnot_GetStringValue(annot, author_key.get(), buf.data(), len));
Jane Liu4fd9a472017-06-01 18:56:09 -040071 EXPECT_STREQ(L"Jae Hyun Park",
72 GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
73 .c_str());
74
75 // Check that the content is correct.
Jane Liu2e1a32b2017-07-06 12:01:25 -040076 std::unique_ptr<unsigned short, pdfium::FreeDeleter> contents_key =
77 GetFPDFWideString(L"Contents");
78 EXPECT_EQ(FPDF_OBJECT_STRING,
79 FPDFAnnot_GetValueType(annot, contents_key.get()));
80 len = FPDFAnnot_GetStringValue(annot, contents_key.get(), nullptr, 0);
Jane Liu4fd9a472017-06-01 18:56:09 -040081 buf.clear();
82 buf.resize(len);
Jane Liu2e1a32b2017-07-06 12:01:25 -040083 EXPECT_EQ(2690u, FPDFAnnot_GetStringValue(annot, contents_key.get(),
84 buf.data(), len));
Jane Liu4fd9a472017-06-01 18:56:09 -040085 const wchar_t contents[] =
86 L"This is a note for that highlight annotation. Very long highlight "
87 "annotation. Long long long Long long longLong long longLong long "
88 "longLong long longLong long longLong long longLong long longLong long "
89 "longLong long longLong long longLong long longLong long longLong long "
90 "longLong long longLong long longLong long longLong long longLong long "
91 "longLong long longLong long longLong long longLong long longLong long "
92 "longLong long longLong long longLong long longLong long longLong long "
93 "longLong long longLong long longLong long longLong long longLong long "
94 "longLong long longLong long longLong long longLong long longLong long "
95 "longLong long longLong long longLong long longLong long longLong long "
96 "longLong long longLong long longLong long longLong long longLong long "
97 "longLong long longLong long longLong long longLong long longLong long "
98 "longLong long longLong long longLong long longLong long longLong long "
99 "longLong long longLong long longLong long longLong long longLong long "
100 "longLong long longLong long longLong long longLong long longLong long "
101 "longLong long longLong long longLong long longLong long longLong long "
102 "longLong long longLong long longLong long longLong long longLong long "
103 "longLong long longLong long longLong long longLong long longLong long "
104 "longLong long longLong long longLong long longLong long longLong long "
105 "longLong long long. END";
106 EXPECT_STREQ(contents,
107 GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
108 .c_str());
109
110 // Check that the quadpoints are correct.
Jane Liud60e9ad2017-06-26 11:28:36 -0400111 FS_QUADPOINTSF quadpoints = FPDFAnnot_GetAttachmentPoints(annot);
Jane Liu4fd9a472017-06-01 18:56:09 -0400112 EXPECT_EQ(115.802643f, quadpoints.x1);
113 EXPECT_EQ(718.913940f, quadpoints.y1);
114 EXPECT_EQ(157.211182f, quadpoints.x4);
115 EXPECT_EQ(706.264465f, quadpoints.y4);
116
Jane Liue10509a2017-06-20 16:47:41 -0400117 FPDFPage_CloseAnnot(annot);
Jane Liu4fd9a472017-06-01 18:56:09 -0400118 UnloadPage(page);
119}
120
121TEST_F(FPDFAnnotEmbeddertest, ExtractInkMultiple) {
122 // Open a file with three annotations and load its first page.
123 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
124 FPDF_PAGE page = FPDF_LoadPage(document(), 0);
125 ASSERT_TRUE(page);
126
127 // Check that there is a total of 3 annotation on its first page.
128 EXPECT_EQ(3, FPDFPage_GetAnnotCount(page));
129
Jane Liu20eafda2017-06-07 10:33:24 -0400130 // Check that the third annotation is of type "ink".
Jane Liud60e9ad2017-06-26 11:28:36 -0400131 FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 2);
132 ASSERT_TRUE(annot);
Jane Liu4fd9a472017-06-01 18:56:09 -0400133 EXPECT_EQ(FPDF_ANNOT_INK, FPDFAnnot_GetSubtype(annot));
134
135 // Check that the annotation color is blue with opacity.
136 unsigned int R;
137 unsigned int G;
138 unsigned int B;
139 unsigned int A;
140 EXPECT_TRUE(
141 FPDFAnnot_GetColor(annot, FPDFANNOT_COLORTYPE_Color, &R, &G, &B, &A));
142 EXPECT_EQ(0u, R);
143 EXPECT_EQ(0u, G);
144 EXPECT_EQ(255u, B);
145 EXPECT_EQ(76u, A);
146
147 // Check that there is no content.
Jane Liu2e1a32b2017-07-06 12:01:25 -0400148 std::unique_ptr<unsigned short, pdfium::FreeDeleter> contents_key =
149 GetFPDFWideString(L"Contents");
Jane Liu4fd9a472017-06-01 18:56:09 -0400150 EXPECT_EQ(2u,
Jane Liu2e1a32b2017-07-06 12:01:25 -0400151 FPDFAnnot_GetStringValue(annot, contents_key.get(), nullptr, 0));
Jane Liu4fd9a472017-06-01 18:56:09 -0400152
153 // Check that the rectange coordinates are correct.
154 // Note that upon rendering, the rectangle coordinates will be adjusted.
Jane Liud60e9ad2017-06-26 11:28:36 -0400155 FS_RECTF rect = FPDFAnnot_GetRect(annot);
Jane Liu4fd9a472017-06-01 18:56:09 -0400156 EXPECT_EQ(351.820404f, rect.left);
157 EXPECT_EQ(583.830688f, rect.bottom);
158 EXPECT_EQ(475.336090f, rect.right);
159 EXPECT_EQ(681.535034f, rect.top);
160
Jane Liue10509a2017-06-20 16:47:41 -0400161 FPDFPage_CloseAnnot(annot);
Jane Liu4fd9a472017-06-01 18:56:09 -0400162 UnloadPage(page);
163}
Jane Liu20eafda2017-06-07 10:33:24 -0400164
165TEST_F(FPDFAnnotEmbeddertest, AddIllegalSubtypeAnnotation) {
166 // Open a file with one annotation and load its first page.
167 ASSERT_TRUE(OpenDocument("annotation_highlight_long_content.pdf"));
168 FPDF_PAGE page = FPDF_LoadPage(document(), 0);
169 ASSERT_TRUE(page);
170
171 // Add an annotation with an illegal subtype.
Jane Liud60e9ad2017-06-26 11:28:36 -0400172 ASSERT_FALSE(FPDFPage_CreateAnnot(page, -1));
Jane Liu20eafda2017-06-07 10:33:24 -0400173
174 UnloadPage(page);
175}
176
Jane Liud321ef92017-06-14 09:56:22 -0400177TEST_F(FPDFAnnotEmbeddertest, AddFirstTextAnnotation) {
Jane Liu20eafda2017-06-07 10:33:24 -0400178 // Open a file with no annotation and load its first page.
179 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
180 FPDF_PAGE page = FPDF_LoadPage(document(), 0);
181 ASSERT_TRUE(page);
182 EXPECT_EQ(0, FPDFPage_GetAnnotCount(page));
183
Jane Liueda65252017-06-07 11:31:27 -0400184 // Add a text annotation to the page.
Jane Liud60e9ad2017-06-26 11:28:36 -0400185 FPDF_ANNOTATION annot = FPDFPage_CreateAnnot(page, FPDF_ANNOT_TEXT);
186 ASSERT_TRUE(annot);
Jane Liu20eafda2017-06-07 10:33:24 -0400187
188 // Check that there is now 1 annotations on this page.
189 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
190
191 // Check that the subtype of the annotation is correct.
192 EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot));
Jane Liue10509a2017-06-20 16:47:41 -0400193 FPDFPage_CloseAnnot(annot);
194
Jane Liud60e9ad2017-06-26 11:28:36 -0400195 annot = FPDFPage_GetAnnot(page, 0);
196 ASSERT_TRUE(annot);
Jane Liu20eafda2017-06-07 10:33:24 -0400197 EXPECT_EQ(FPDF_ANNOT_TEXT, FPDFAnnot_GetSubtype(annot));
198
199 // Set the color of the annotation.
200 ASSERT_TRUE(
201 FPDFAnnot_SetColor(annot, FPDFANNOT_COLORTYPE_Color, 51, 102, 153, 204));
202 // Check that the color has been set correctly.
203 unsigned int R;
204 unsigned int G;
205 unsigned int B;
206 unsigned int A;
207 EXPECT_TRUE(
208 FPDFAnnot_GetColor(annot, FPDFANNOT_COLORTYPE_Color, &R, &G, &B, &A));
209 EXPECT_EQ(51u, R);
210 EXPECT_EQ(102u, G);
211 EXPECT_EQ(153u, B);
212 EXPECT_EQ(204u, A);
213
214 // Change the color of the annotation.
215 ASSERT_TRUE(
216 FPDFAnnot_SetColor(annot, FPDFANNOT_COLORTYPE_Color, 204, 153, 102, 51));
217 // Check that the color has been set correctly.
218 EXPECT_TRUE(
219 FPDFAnnot_GetColor(annot, FPDFANNOT_COLORTYPE_Color, &R, &G, &B, &A));
220 EXPECT_EQ(204u, R);
221 EXPECT_EQ(153u, G);
222 EXPECT_EQ(102u, B);
223 EXPECT_EQ(51u, A);
224
225 // Set the annotation rectangle.
Jane Liud60e9ad2017-06-26 11:28:36 -0400226 FS_RECTF rect = FPDFAnnot_GetRect(annot);
227 EXPECT_EQ(0.f, rect.left);
228 EXPECT_EQ(0.f, rect.right);
Jane Liu20eafda2017-06-07 10:33:24 -0400229 rect.left = 35;
230 rect.bottom = 150;
231 rect.right = 53;
232 rect.top = 165;
Jane Liu06462752017-06-27 16:41:14 -0400233 ASSERT_TRUE(FPDFAnnot_SetRect(annot, &rect));
Jane Liu20eafda2017-06-07 10:33:24 -0400234 // Check that the annotation rectangle has been set correctly.
Jane Liud60e9ad2017-06-26 11:28:36 -0400235 rect = FPDFAnnot_GetRect(annot);
Jane Liu20eafda2017-06-07 10:33:24 -0400236 EXPECT_EQ(35.f, rect.left);
237 EXPECT_EQ(150.f, rect.bottom);
238 EXPECT_EQ(53.f, rect.right);
239 EXPECT_EQ(165.f, rect.top);
240
241 // Set the content of the annotation.
Jane Liu2e1a32b2017-07-06 12:01:25 -0400242 std::unique_ptr<unsigned short, pdfium::FreeDeleter> contents_key =
243 GetFPDFWideString(L"Contents");
Jane Liu20eafda2017-06-07 10:33:24 -0400244 const wchar_t contents[] = L"Hello! This is a customized content.";
245 std::unique_ptr<unsigned short, pdfium::FreeDeleter> text =
246 GetFPDFWideString(contents);
Jane Liu2e1a32b2017-07-06 12:01:25 -0400247 ASSERT_TRUE(FPDFAnnot_SetStringValue(annot, contents_key.get(), text.get()));
Jane Liu20eafda2017-06-07 10:33:24 -0400248 // Check that the content has been set correctly.
249 unsigned long len =
Jane Liu2e1a32b2017-07-06 12:01:25 -0400250 FPDFAnnot_GetStringValue(annot, contents_key.get(), nullptr, 0);
Jane Liu20eafda2017-06-07 10:33:24 -0400251 std::vector<char> buf(len);
Jane Liu2e1a32b2017-07-06 12:01:25 -0400252 EXPECT_EQ(74u, FPDFAnnot_GetStringValue(annot, contents_key.get(), buf.data(),
253 len));
Jane Liu20eafda2017-06-07 10:33:24 -0400254 EXPECT_STREQ(contents,
255 GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
256 .c_str());
257
Jane Liue10509a2017-06-20 16:47:41 -0400258 FPDFPage_CloseAnnot(annot);
Jane Liu20eafda2017-06-07 10:33:24 -0400259 UnloadPage(page);
260}
261
262TEST_F(FPDFAnnotEmbeddertest, AddAndSaveUnderlineAnnotation) {
263 // Open a file with one annotation and load its first page.
264 ASSERT_TRUE(OpenDocument("annotation_highlight_long_content.pdf"));
265 FPDF_PAGE page = FPDF_LoadPage(document(), 0);
266 ASSERT_TRUE(page);
267
268 // Check that there is a total of one annotation on its first page, and verify
269 // its quadpoints.
270 EXPECT_EQ(1, FPDFPage_GetAnnotCount(page));
Jane Liud60e9ad2017-06-26 11:28:36 -0400271 FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 0);
272 ASSERT_TRUE(annot);
273 FS_QUADPOINTSF quadpoints = FPDFAnnot_GetAttachmentPoints(annot);
Jane Liu20eafda2017-06-07 10:33:24 -0400274 EXPECT_EQ(115.802643f, quadpoints.x1);
275 EXPECT_EQ(718.913940f, quadpoints.y1);
276 EXPECT_EQ(157.211182f, quadpoints.x4);
277 EXPECT_EQ(706.264465f, quadpoints.y4);
Jane Liue10509a2017-06-20 16:47:41 -0400278 FPDFPage_CloseAnnot(annot);
Jane Liu20eafda2017-06-07 10:33:24 -0400279
280 // Add an underline annotation to the page and set its quadpoints.
Jane Liud60e9ad2017-06-26 11:28:36 -0400281 annot = FPDFPage_CreateAnnot(page, FPDF_ANNOT_UNDERLINE);
282 ASSERT_TRUE(annot);
Jane Liu20eafda2017-06-07 10:33:24 -0400283 quadpoints.x1 = 140.802643f;
284 quadpoints.x3 = 140.802643f;
Jane Liu06462752017-06-27 16:41:14 -0400285 ASSERT_TRUE(FPDFAnnot_SetAttachmentPoints(annot, &quadpoints));
Jane Liue10509a2017-06-20 16:47:41 -0400286 FPDFPage_CloseAnnot(annot);
Jane Liu20eafda2017-06-07 10:33:24 -0400287
288 // Save the document, closing the page and document.
289 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
290 FPDF_ClosePage(page);
291
292 // Open the saved document.
Nicolas Pena3ff54002017-07-05 11:55:35 -0400293 const char md5[] = "184b67b322edaee27994b3232544b8b3";
294 TestSaved(612, 792, md5);
Jane Liu20eafda2017-06-07 10:33:24 -0400295
296 // Check that the saved document has 2 annotations on the first page
Nicolas Pena3ff54002017-07-05 11:55:35 -0400297 EXPECT_EQ(2, FPDFPage_GetAnnotCount(m_SavedPage));
Jane Liu20eafda2017-06-07 10:33:24 -0400298
299 // Check that the second annotation is an underline annotation and verify
300 // its quadpoints.
Nicolas Pena3ff54002017-07-05 11:55:35 -0400301 FPDF_ANNOTATION new_annot = FPDFPage_GetAnnot(m_SavedPage, 1);
Jane Liud60e9ad2017-06-26 11:28:36 -0400302 ASSERT_TRUE(new_annot);
Jane Liu20eafda2017-06-07 10:33:24 -0400303 EXPECT_EQ(FPDF_ANNOT_UNDERLINE, FPDFAnnot_GetSubtype(new_annot));
Jane Liud60e9ad2017-06-26 11:28:36 -0400304 FS_QUADPOINTSF new_quadpoints = FPDFAnnot_GetAttachmentPoints(new_annot);
Jane Liu20eafda2017-06-07 10:33:24 -0400305 EXPECT_NEAR(quadpoints.x1, new_quadpoints.x1, 0.001f);
306 EXPECT_NEAR(quadpoints.y1, new_quadpoints.y1, 0.001f);
307 EXPECT_NEAR(quadpoints.x4, new_quadpoints.x4, 0.001f);
308 EXPECT_NEAR(quadpoints.y4, new_quadpoints.y4, 0.001f);
309
Jane Liue10509a2017-06-20 16:47:41 -0400310 FPDFPage_CloseAnnot(new_annot);
Nicolas Pena3ff54002017-07-05 11:55:35 -0400311 CloseSaved();
Jane Liu20eafda2017-06-07 10:33:24 -0400312}
Jane Liu06462752017-06-27 16:41:14 -0400313
314TEST_F(FPDFAnnotEmbeddertest, ModifyRectQuadpointsWithAP) {
315 // Open a file with four annotations and load its first page.
316 ASSERT_TRUE(OpenDocument("annotation_highlight_square_with_ap.pdf"));
317 FPDF_PAGE page = FPDF_LoadPage(document(), 0);
318 ASSERT_TRUE(page);
319 EXPECT_EQ(4, FPDFPage_GetAnnotCount(page));
320
321 // Retrieve the highlight annotation which has its AP stream already defined.
322 FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 0);
323 ASSERT_TRUE(annot);
324 EXPECT_EQ(FPDF_ANNOT_HIGHLIGHT, FPDFAnnot_GetSubtype(annot));
325
326 // Check that color cannot be set when an AP stream is defined already.
327 EXPECT_FALSE(
328 FPDFAnnot_SetColor(annot, FPDFANNOT_COLORTYPE_Color, 51, 102, 153, 204));
329
330 // Check that when getting the attachment points, bounding box points are
331 // returned since this is a markup annotation with AP defined.
332 FS_QUADPOINTSF quadpoints = FPDFAnnot_GetAttachmentPoints(annot);
333 EXPECT_NEAR(0.f, quadpoints.x1, 0.001f);
334 EXPECT_NEAR(16.9955f, quadpoints.y1, 0.001f);
335 EXPECT_NEAR(68.5953f, quadpoints.x4, 0.001f);
336 EXPECT_NEAR(0.f, quadpoints.y4, 0.001f);
337
338 // Check that when new attachment points define a smaller bounding box, the
339 // bounding box does not get updated.
340 quadpoints.x1 = 1.0f;
341 quadpoints.x3 = 1.0f;
342 ASSERT_TRUE(FPDFAnnot_SetAttachmentPoints(annot, &quadpoints));
343 FS_QUADPOINTSF new_quadpoints = FPDFAnnot_GetAttachmentPoints(annot);
344 EXPECT_NE(quadpoints.x1, new_quadpoints.x1);
345
346 // Check that the bounding box gets updated successfully when valid attachment
347 // points are set.
348 quadpoints.x1 = 0.f;
349 quadpoints.y1 = 721.792f;
350 quadpoints.x2 = 133.055f;
351 quadpoints.y2 = 721.792f;
352 quadpoints.x3 = 0.f;
353 quadpoints.x4 = 133.055f;
354 ASSERT_TRUE(FPDFAnnot_SetAttachmentPoints(annot, &quadpoints));
355 new_quadpoints = FPDFAnnot_GetAttachmentPoints(annot);
356 EXPECT_EQ(quadpoints.x1, new_quadpoints.x1);
357 EXPECT_EQ(quadpoints.y1, new_quadpoints.y1);
358 EXPECT_EQ(quadpoints.x4, new_quadpoints.x4);
359 EXPECT_EQ(quadpoints.y4, new_quadpoints.y4);
360
361 // Check that when getting the annotation rectangle, rectangle points are
362 // returned, but not bounding box points.
363 FS_RECTF rect = FPDFAnnot_GetRect(annot);
364 EXPECT_NEAR(67.7299f, rect.left, 0.001f);
365 EXPECT_NEAR(704.296f, rect.bottom, 0.001f);
366 EXPECT_NEAR(136.325f, rect.right, 0.001f);
367 EXPECT_NEAR(721.292f, rect.top, 0.001f);
368
369 // Check that the rectangle gets updated successfully when a valid rectangle
370 // is set, and that the bounding box is not modified.
371 rect.left = 0.f;
372 rect.bottom = 0.f;
373 rect.right = 134.055f;
374 rect.top = 722.792f;
375 ASSERT_TRUE(FPDFAnnot_SetRect(annot, &rect));
376 FS_RECTF new_rect = FPDFAnnot_GetRect(annot);
377 EXPECT_EQ(rect.right, new_rect.right);
378 new_quadpoints = FPDFAnnot_GetAttachmentPoints(annot);
379 EXPECT_NE(rect.right, new_quadpoints.x2);
380
381 FPDFPage_CloseAnnot(annot);
382
383 // Retrieve the square annotation which has its AP stream already defined.
384 annot = FPDFPage_GetAnnot(page, 2);
385 ASSERT_TRUE(annot);
386 EXPECT_EQ(FPDF_ANNOT_SQUARE, FPDFAnnot_GetSubtype(annot));
387
388 // Check that the rectangle and the bounding box get updated successfully when
389 // a valid rectangle is set, since this is not a markup annotation.
390 rect = FPDFAnnot_GetRect(annot);
391 rect.right += 1.f;
392 ASSERT_TRUE(FPDFAnnot_SetRect(annot, &rect));
393 new_rect = FPDFAnnot_GetRect(annot);
394 EXPECT_EQ(rect.right, new_rect.right);
395
396 FPDFPage_CloseAnnot(annot);
397 UnloadPage(page);
398}
Jane Liu8ce58f52017-06-29 13:40:22 -0400399
400TEST_F(FPDFAnnotEmbeddertest, RemoveAnnotation) {
401 // Open a file with 3 annotations on its first page.
402 ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf"));
403 FPDF_PAGE page = FPDF_LoadPage(document(), 0);
404 ASSERT_TRUE(page);
405 EXPECT_EQ(3, FPDFPage_GetAnnotCount(page));
406
407 // Check that the annotations have the expected rectangle coordinates.
408 FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 0);
409 FS_RECTF rect = FPDFAnnot_GetRect(annot);
410 EXPECT_NEAR(86.1971f, rect.left, 0.001f);
411 FPDFPage_CloseAnnot(annot);
412
413 annot = FPDFPage_GetAnnot(page, 1);
414 rect = FPDFAnnot_GetRect(annot);
415 EXPECT_NEAR(149.8127f, rect.left, 0.001f);
416 FPDFPage_CloseAnnot(annot);
417
418 annot = FPDFPage_GetAnnot(page, 2);
419 rect = FPDFAnnot_GetRect(annot);
420 EXPECT_NEAR(351.8204f, rect.left, 0.001f);
421 FPDFPage_CloseAnnot(annot);
422
423 // Check that nothing happens when attempting to remove an annotation with an
424 // out-of-bound index.
425 EXPECT_FALSE(FPDFPage_RemoveAnnot(page, 4));
426 EXPECT_FALSE(FPDFPage_RemoveAnnot(page, -1));
427 EXPECT_EQ(3, FPDFPage_GetAnnotCount(page));
428
429 // Remove the second annotation.
430 EXPECT_TRUE(FPDFPage_RemoveAnnot(page, 1));
431 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
432 EXPECT_FALSE(FPDFPage_GetAnnot(page, 2));
433
434 // Save the document, closing the page and document.
435 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
436 FPDF_ClosePage(page);
437
Nicolas Pena3ff54002017-07-05 11:55:35 -0400438 // TODO(npm): TestSaved changes annot rect dimensions by 1??
Jane Liu8ce58f52017-06-29 13:40:22 -0400439 // Open the saved document.
440 std::string new_file = GetString();
441 FPDF_FILEACCESS file_access;
442 memset(&file_access, 0, sizeof(file_access));
443 file_access.m_FileLen = new_file.size();
444 file_access.m_GetBlock = GetBlockFromString;
445 file_access.m_Param = &new_file;
446 FPDF_DOCUMENT new_doc = FPDF_LoadCustomDocument(&file_access, nullptr);
447 ASSERT_TRUE(new_doc);
448 FPDF_PAGE new_page = FPDF_LoadPage(new_doc, 0);
449 ASSERT_TRUE(new_page);
450
451 // Check that the saved document has 2 annotations on the first page.
452 EXPECT_EQ(2, FPDFPage_GetAnnotCount(new_page));
453
454 // Check that the remaining 2 annotations are the original 1st and 3rd ones by
455 // verifying their rectangle coordinates.
456 annot = FPDFPage_GetAnnot(new_page, 0);
457 rect = FPDFAnnot_GetRect(annot);
458 EXPECT_NEAR(86.1971f, rect.left, 0.001f);
459 FPDFPage_CloseAnnot(annot);
460
461 annot = FPDFPage_GetAnnot(new_page, 1);
462 rect = FPDFAnnot_GetRect(annot);
463 EXPECT_NEAR(351.8204f, rect.left, 0.001f);
464 FPDFPage_CloseAnnot(annot);
Jane Liubaa7ff42017-06-29 19:18:23 -0400465 FPDF_ClosePage(new_page);
466 FPDF_CloseDocument(new_doc);
467}
Jane Liu8ce58f52017-06-29 13:40:22 -0400468
Jane Liubaa7ff42017-06-29 19:18:23 -0400469TEST_F(FPDFAnnotEmbeddertest, AddAndModifyPath) {
470#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
471 const char md5[] = "c35408717759562d1f8bf33d317483d2";
472 const char md5_2[] = "cf3cea74bd46497520ff6c4d1ea228c8";
473 const char md5_3[] = "ee5372b31fede117fc83b9384598aa25";
474#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
475 const char md5[] = "bdf96279ab82d9f484874db3f0c03429";
476 const char md5_2[] = "5f2b32b7aa93bc1e62a7a7971f54bdd7";
477 const char md5_3[] = "272661f3e5c9516aac4b5beb3ae1b36a";
478#else
479 const char md5[] = "07d4168715553b4294525f840c40aa1c";
480 const char md5_2[] = "dd5ba8996af67d0e5add418195e4d61b";
481 const char md5_3[] = "c60c2cc2c4e7b13be90bd77cc4502f97";
482#endif
483
484 // Open a file with two annotations and load its first page.
485 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
486 FPDF_PAGE page = FPDF_LoadPage(document(), 0);
487 ASSERT_TRUE(page);
488 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
489
490 // Check that the page renders correctly.
491 FPDF_BITMAP bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT);
492 CompareBitmap(bitmap, 595, 842, md5);
493 FPDFBitmap_Destroy(bitmap);
494
495 // Retrieve the stamp annotation which has its AP stream already defined.
496 FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 0);
497 ASSERT_TRUE(annot);
498
499 // Check that this annotation has one path object and retrieve it.
Jane Liu36567742017-07-06 11:13:35 -0400500 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot));
501 FPDF_PAGEOBJECT path = FPDFAnnot_GetObject(annot, 1);
Jane Liubaa7ff42017-06-29 19:18:23 -0400502 EXPECT_FALSE(path);
Jane Liu36567742017-07-06 11:13:35 -0400503 path = FPDFAnnot_GetObject(annot, 0);
504 EXPECT_EQ(FPDF_PAGEOBJ_PATH, FPDFPageObj_GetType(path));
Jane Liubaa7ff42017-06-29 19:18:23 -0400505 EXPECT_TRUE(path);
506
507 // Modify the color of the path object.
508 EXPECT_TRUE(FPDFPath_SetStrokeColor(path, 0, 0, 0, 255));
Jane Liu36567742017-07-06 11:13:35 -0400509 EXPECT_TRUE(FPDFAnnot_UpdateObject(annot, path));
Jane Liubaa7ff42017-06-29 19:18:23 -0400510 FPDFPage_CloseAnnot(annot);
511
512 // Check that the page with the modified annotation renders correctly.
513 bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT);
514 CompareBitmap(bitmap, 595, 842, md5_2);
515 FPDFBitmap_Destroy(bitmap);
516
517 // Create another stamp annotation and set its annotation rectangle.
518 annot = FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP);
519 ASSERT_TRUE(annot);
520 FS_RECTF rect;
521 rect.left = 200.f;
522 rect.bottom = 400.f;
523 rect.right = 500.f;
524 rect.top = 600.f;
525 EXPECT_TRUE(FPDFAnnot_SetRect(annot, &rect));
526
527 // Add a new path to the annotation.
528 FPDF_PAGEOBJECT check = FPDFPageObj_CreateNewPath(200, 500);
529 EXPECT_TRUE(FPDFPath_LineTo(check, 300, 400));
530 EXPECT_TRUE(FPDFPath_LineTo(check, 500, 600));
531 EXPECT_TRUE(FPDFPath_MoveTo(check, 350, 550));
532 EXPECT_TRUE(FPDFPath_LineTo(check, 450, 450));
533 EXPECT_TRUE(FPDFPath_SetStrokeColor(check, 0, 255, 255, 180));
534 EXPECT_TRUE(FPDFPath_SetStrokeWidth(check, 8.35f));
535 EXPECT_TRUE(FPDFPath_SetDrawMode(check, 0, 1));
Jane Liu36567742017-07-06 11:13:35 -0400536 EXPECT_TRUE(FPDFAnnot_AppendObject(annot, check));
537 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot));
Jane Liubaa7ff42017-06-29 19:18:23 -0400538
539 // Check that the annotation's bounding box came from its rectangle.
540 FS_RECTF new_rect = FPDFAnnot_GetRect(annot);
541 EXPECT_EQ(rect.left, new_rect.left);
542 EXPECT_EQ(rect.bottom, new_rect.bottom);
543 EXPECT_EQ(rect.right, new_rect.right);
544 EXPECT_EQ(rect.top, new_rect.top);
545
546 // Save the document, closing the page and document.
547 FPDFPage_CloseAnnot(annot);
548 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
549 FPDF_ClosePage(page);
550
551 // Open the saved document.
Nicolas Pena3ff54002017-07-05 11:55:35 -0400552 TestSaved(595, 842, md5_3);
Jane Liubaa7ff42017-06-29 19:18:23 -0400553
Jane Liu36567742017-07-06 11:13:35 -0400554 // Check that the document has a correct count of annotations and objects.
Nicolas Pena3ff54002017-07-05 11:55:35 -0400555 EXPECT_EQ(3, FPDFPage_GetAnnotCount(m_SavedPage));
556 annot = FPDFPage_GetAnnot(m_SavedPage, 2);
Jane Liubaa7ff42017-06-29 19:18:23 -0400557 ASSERT_TRUE(annot);
Jane Liu36567742017-07-06 11:13:35 -0400558 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot));
Jane Liubaa7ff42017-06-29 19:18:23 -0400559
560 // Check that the new annotation's rectangle is as defined.
561 new_rect = FPDFAnnot_GetRect(annot);
562 EXPECT_EQ(rect.left, new_rect.left);
563 EXPECT_EQ(rect.bottom, new_rect.bottom);
564 EXPECT_EQ(rect.right, new_rect.right);
565 EXPECT_EQ(rect.top, new_rect.top);
566
Jane Liubaa7ff42017-06-29 19:18:23 -0400567 FPDFPage_CloseAnnot(annot);
Nicolas Pena3ff54002017-07-05 11:55:35 -0400568 CloseSaved();
Jane Liu8ce58f52017-06-29 13:40:22 -0400569}
Jane Liub137e752017-07-05 15:04:33 -0400570
571TEST_F(FPDFAnnotEmbeddertest, ModifyAnnotationFlags) {
572 // Open a file with an annotation and load its first page.
573 ASSERT_TRUE(OpenDocument("annotation_highlight_rollover_ap.pdf"));
574 FPDF_PAGE page = FPDF_LoadPage(document(), 0);
575 ASSERT_TRUE(page);
576
577 // Check that the page renders correctly.
578 FPDF_BITMAP bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT);
579 CompareBitmap(bitmap, 612, 792, "dc98f06da047bd8aabfa99562d2cbd1e");
580 FPDFBitmap_Destroy(bitmap);
581
582 // Retrieve the annotation.
583 FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 0);
584 ASSERT_TRUE(annot);
585
586 // Check that the original flag values are as expected.
587 int flags = FPDFAnnot_GetFlags(annot);
588 EXPECT_FALSE(flags & FPDF_ANNOT_FLAG_HIDDEN);
589 EXPECT_TRUE(flags & FPDF_ANNOT_FLAG_PRINT);
590
591 // Set the HIDDEN flag.
592 flags |= FPDF_ANNOT_FLAG_HIDDEN;
593 EXPECT_TRUE(FPDFAnnot_SetFlags(annot, flags));
594 flags = FPDFAnnot_GetFlags(annot);
595 EXPECT_TRUE(flags & FPDF_ANNOT_FLAG_HIDDEN);
596 EXPECT_TRUE(flags & FPDF_ANNOT_FLAG_PRINT);
597
598 // Check that the page renders correctly without rendering the annotation.
599 bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT);
600 CompareBitmap(bitmap, 612, 792, "1940568c9ba33bac5d0b1ee9558c76b3");
601 FPDFBitmap_Destroy(bitmap);
602
603 // Unset the HIDDEN flag.
604 EXPECT_TRUE(FPDFAnnot_SetFlags(annot, FPDF_ANNOT_FLAG_NONE));
605 EXPECT_FALSE(FPDFAnnot_GetFlags(annot));
606 flags &= ~FPDF_ANNOT_FLAG_HIDDEN;
607 EXPECT_TRUE(FPDFAnnot_SetFlags(annot, flags));
608 flags = FPDFAnnot_GetFlags(annot);
609 EXPECT_FALSE(flags & FPDF_ANNOT_FLAG_HIDDEN);
610 EXPECT_TRUE(flags & FPDF_ANNOT_FLAG_PRINT);
611
612 // Check that the page renders correctly as before.
613 bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT);
614 CompareBitmap(bitmap, 612, 792, "dc98f06da047bd8aabfa99562d2cbd1e");
615 FPDFBitmap_Destroy(bitmap);
616
617 FPDFPage_CloseAnnot(annot);
618 UnloadPage(page);
619}
Jane Liu36567742017-07-06 11:13:35 -0400620
621TEST_F(FPDFAnnotEmbeddertest, AddAndModifyImage) {
622#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
623 const char md5[] = "c35408717759562d1f8bf33d317483d2";
624 const char md5_2[] = "ff012f5697436dfcaec25b32d1333596";
625 const char md5_3[] = "86cf8cb2755a7a2046a543e66d9c1e61";
626#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
627 const char md5[] = "bdf96279ab82d9f484874db3f0c03429";
628 const char md5_2[] = "048a9af8b6239b59a19dacd8e1688e0a";
629 const char md5_3[] = "3be8aa2ebc927e32060e7116dd937a14";
630#else
631 const char md5[] = "07d4168715553b4294525f840c40aa1c";
632 const char md5_2[] = "9685b2a0cf11ee730125f88ab10ff1d0";
633 const char md5_3[] = "0763407baf3656b8061bbbe698e9fd89";
634#endif
635
636 // Open a file with two annotations and load its first page.
637 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
638 FPDF_PAGE page = FPDF_LoadPage(document(), 0);
639 ASSERT_TRUE(page);
640 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
641
642 // Check that the page renders correctly.
643 FPDF_BITMAP bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT);
644 CompareBitmap(bitmap, 595, 842, md5);
645 FPDFBitmap_Destroy(bitmap);
646
647 // Create a stamp annotation and set its annotation rectangle.
648 FPDF_ANNOTATION annot = FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP);
649 ASSERT_TRUE(annot);
650 FS_RECTF rect;
651 rect.left = 200.f;
652 rect.bottom = 600.f;
653 rect.right = 400.f;
654 rect.top = 800.f;
655 EXPECT_TRUE(FPDFAnnot_SetRect(annot, &rect));
656
657 // Add a solid-color translucent image object to the new annotation.
658 constexpr int kBitmapSize = 200;
659 FPDF_BITMAP image_bitmap = FPDFBitmap_Create(kBitmapSize, kBitmapSize, 1);
660 FPDFBitmap_FillRect(image_bitmap, 0, 0, kBitmapSize, kBitmapSize, 0xeeeecccc);
661 EXPECT_EQ(kBitmapSize, FPDFBitmap_GetWidth(image_bitmap));
662 EXPECT_EQ(kBitmapSize, FPDFBitmap_GetHeight(image_bitmap));
663 FPDF_PAGEOBJECT image_object = FPDFPageObj_NewImageObj(document());
664 ASSERT_TRUE(FPDFImageObj_SetBitmap(&page, 0, image_object, image_bitmap));
665 ASSERT_TRUE(FPDFImageObj_SetMatrix(image_object, kBitmapSize, 0, 0,
666 kBitmapSize, 0, 0));
667 FPDFPageObj_Transform(image_object, 1, 0, 0, 1, 200, 600);
668 EXPECT_TRUE(FPDFAnnot_AppendObject(annot, image_object));
669 FPDFPage_CloseAnnot(annot);
670
671 // Check that the page renders correctly with the new image object.
672 bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT);
673 CompareBitmap(bitmap, 595, 842, md5_2);
674 FPDFBitmap_Destroy(bitmap);
675
676 // Retrieve the newly added stamp annotation and its image object.
677 annot = FPDFPage_GetAnnot(page, 2);
678 ASSERT_TRUE(annot);
679 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot));
680 image_object = FPDFAnnot_GetObject(annot, 0);
681 EXPECT_EQ(FPDF_PAGEOBJ_IMAGE, FPDFPageObj_GetType(image_object));
682
683 // Modify the image in the new annotation.
684 FPDFBitmap_FillRect(image_bitmap, 0, 0, kBitmapSize, kBitmapSize, 0xff000000);
685 ASSERT_TRUE(FPDFImageObj_SetBitmap(&page, 0, image_object, image_bitmap));
686 EXPECT_TRUE(FPDFAnnot_UpdateObject(annot, image_object));
687 FPDFPage_CloseAnnot(annot);
688
689 // Save the document, closing the page and document.
690 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
691 FPDF_ClosePage(page);
692
693 // Test that the saved document renders the modified image object correctly.
694 TestSaved(595, 842, md5_3);
695
696 FPDFBitmap_Destroy(image_bitmap);
697 CloseSaved();
698}
699
700TEST_F(FPDFAnnotEmbeddertest, AddAndModifyText) {
701#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
702 const char md5[] = "c35408717759562d1f8bf33d317483d2";
703 const char md5_2[] = "e5680ed048c2cfd9a1d27212cdf41286";
704 const char md5_3[] = "79f5cfb0b07caaf936f65f6a7a57ce77";
705#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
706 const char md5[] = "bdf96279ab82d9f484874db3f0c03429";
707 const char md5_2[] = "fa5709c115d4ebd502df91841b44b3ef";
708 const char md5_3[] = "9f6fa52dc477ccf52be4184d8589ef3f";
709#else
710 const char md5[] = "07d4168715553b4294525f840c40aa1c";
711 const char md5_2[] = "40a4c5e0561b062882b47253be3393ef";
712 const char md5_3[] = "f8ce0682add01f6d273890ac64d90fa6";
713#endif
714
715 // Open a file with two annotations and load its first page.
716 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
717 FPDF_PAGE page = FPDF_LoadPage(document(), 0);
718 ASSERT_TRUE(page);
719 EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
720
721 // Check that the page renders correctly.
722 FPDF_BITMAP bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT);
723 CompareBitmap(bitmap, 595, 842, md5);
724 FPDFBitmap_Destroy(bitmap);
725
726 // Create a stamp annotation and set its annotation rectangle.
727 FPDF_ANNOTATION annot = FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP);
728 ASSERT_TRUE(annot);
729 FS_RECTF rect;
730 rect.left = 200.f;
731 rect.bottom = 550.f;
732 rect.right = 450.f;
733 rect.top = 650.f;
734 EXPECT_TRUE(FPDFAnnot_SetRect(annot, &rect));
735
736 // Add a translucent text object to the new annotation.
737 FPDF_PAGEOBJECT text_object =
738 FPDFPageObj_NewTextObj(document(), "Arial", 12.0f);
739 EXPECT_TRUE(text_object);
740 std::unique_ptr<unsigned short, pdfium::FreeDeleter> text =
741 GetFPDFWideString(L"I'm a translucent text laying on other text.");
742 EXPECT_TRUE(FPDFText_SetText(text_object, text.get()));
743 EXPECT_TRUE(FPDFText_SetFillColor(text_object, 0, 0, 255, 150));
744 FPDFPageObj_Transform(text_object, 1, 0, 0, 1, 200, 600);
745 EXPECT_TRUE(FPDFAnnot_AppendObject(annot, text_object));
746 FPDFPage_CloseAnnot(annot);
747
748 // Check that the page renders correctly with the new text object.
749 bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT);
750 CompareBitmap(bitmap, 595, 842, md5_2);
751 FPDFBitmap_Destroy(bitmap);
752
753 // Retrieve the newly added stamp annotation and its text object.
754 annot = FPDFPage_GetAnnot(page, 2);
755 ASSERT_TRUE(annot);
756 EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot));
757 text_object = FPDFAnnot_GetObject(annot, 0);
758 EXPECT_EQ(FPDF_PAGEOBJ_TEXT, FPDFPageObj_GetType(text_object));
759
760 // Modify the text in the new annotation.
761 std::unique_ptr<unsigned short, pdfium::FreeDeleter> new_text =
762 GetFPDFWideString(L"New text!");
763 EXPECT_TRUE(FPDFText_SetText(text_object, new_text.get()));
764 EXPECT_TRUE(FPDFAnnot_UpdateObject(annot, text_object));
765 FPDFPage_CloseAnnot(annot);
766
767 // Check that the page renders correctly with the modified text object.
768 bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT);
769 CompareBitmap(bitmap, 595, 842, md5_3);
770 FPDFBitmap_Destroy(bitmap);
771
772 // Remove the new annotation, and check that the page renders as before.
773 EXPECT_TRUE(FPDFPage_RemoveAnnot(page, 2));
774 bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT);
775 CompareBitmap(bitmap, 595, 842, md5);
776 FPDFBitmap_Destroy(bitmap);
777
778 UnloadPage(page);
779}
Jane Liu2e1a32b2017-07-06 12:01:25 -0400780
781TEST_F(FPDFAnnotEmbeddertest, GetSetStringValue) {
782 // Open a file with four annotations and load its first page.
783 ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
784 FPDF_PAGE page = FPDF_LoadPage(document(), 0);
785 ASSERT_TRUE(page);
786
787 // Retrieve the first annotation.
788 FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 0);
789 ASSERT_TRUE(annot);
790
791 // Check that a non-existent key does not exist.
792 EXPECT_FALSE(FPDFAnnot_HasKey(annot, GetFPDFWideString(L"none").get()));
793
794 // Check that the string value of a non-string dictionary entry is empty.
795 std::unique_ptr<unsigned short, pdfium::FreeDeleter> ap_key =
796 GetFPDFWideString(L"AP");
797 EXPECT_TRUE(FPDFAnnot_HasKey(annot, ap_key.get()));
798 EXPECT_EQ(FPDF_OBJECT_REFERENCE, FPDFAnnot_GetValueType(annot, ap_key.get()));
799 EXPECT_EQ(2u, FPDFAnnot_GetStringValue(annot, ap_key.get(), nullptr, 0));
800
801 // Check that the string value of the hash is correct.
802 std::unique_ptr<unsigned short, pdfium::FreeDeleter> hash_key =
803 GetFPDFWideString(L"AAPL:Hash");
804 EXPECT_EQ(FPDF_OBJECT_NAME, FPDFAnnot_GetValueType(annot, hash_key.get()));
805 unsigned long len =
806 FPDFAnnot_GetStringValue(annot, hash_key.get(), nullptr, 0);
807 std::vector<char> buf(len);
808 EXPECT_EQ(66u,
809 FPDFAnnot_GetStringValue(annot, hash_key.get(), buf.data(), len));
810 EXPECT_STREQ(L"395fbcb98d558681742f30683a62a2ad",
811 GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
812 .c_str());
813
814 // Check that the string value of the modified date is correct.
815 std::unique_ptr<unsigned short, pdfium::FreeDeleter> date_key =
816 GetFPDFWideString(L"M");
817 EXPECT_EQ(FPDF_OBJECT_NAME, FPDFAnnot_GetValueType(annot, hash_key.get()));
818 len = FPDFAnnot_GetStringValue(annot, date_key.get(), nullptr, 0);
819 buf.clear();
820 buf.resize(len);
821 EXPECT_EQ(44u,
822 FPDFAnnot_GetStringValue(annot, date_key.get(), buf.data(), len));
823 EXPECT_STREQ(L"D:201706071721Z00'00'",
824 GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
825 .c_str());
826
827 // Update the date entry for the annotation.
828 const wchar_t new_date[] = L"D:201706282359Z00'00'";
829 std::unique_ptr<unsigned short, pdfium::FreeDeleter> text =
830 GetFPDFWideString(new_date);
831 EXPECT_TRUE(FPDFAnnot_SetStringValue(annot, date_key.get(), text.get()));
832
833 // Save the document, closing the page and document.
834 FPDFPage_CloseAnnot(annot);
835 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
836 FPDF_ClosePage(page);
837
838 // Open the saved annotation.
839#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
840 const char md5[] = "c35408717759562d1f8bf33d317483d2";
841#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
842 const char md5[] = "bdf96279ab82d9f484874db3f0c03429";
843#else
844 const char md5[] = "07d4168715553b4294525f840c40aa1c";
845#endif
846 TestSaved(595, 842, md5);
847 FPDF_ANNOTATION new_annot = FPDFPage_GetAnnot(m_SavedPage, 0);
848
849 // Check that the string value of the modified date is the newly-set value.
850 EXPECT_EQ(FPDF_OBJECT_STRING,
851 FPDFAnnot_GetValueType(new_annot, date_key.get()));
852 len = FPDFAnnot_GetStringValue(new_annot, date_key.get(), nullptr, 0);
853 buf.clear();
854 buf.resize(len);
855 EXPECT_EQ(44u, FPDFAnnot_GetStringValue(new_annot, date_key.get(), buf.data(),
856 len));
857 EXPECT_STREQ(new_date,
858 GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
859 .c_str());
860
861 FPDFPage_CloseAnnot(new_annot);
862 CloseSaved();
863}