Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
fpdf_structtree_embeddertest.cpp
Go to the documentation of this file.
1// Copyright 2016 The PDFium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <limits.h>
6
7#include <iterator>
8#include <optional>
9
10#include "core/fxcrt/stl_util.h"
11#include "public/fpdf_structtree.h"
12#include "testing/embedder_test.h"
13#include "testing/fx_string_testhelpers.h"
14
16
18 ASSERT_TRUE(OpenDocument("tagged_alt_text.pdf"));
19 FPDF_PAGE page = LoadPage(0);
20 ASSERT_TRUE(page);
21
22 {
23 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
24 ASSERT_TRUE(struct_tree);
25 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
26
27 FPDF_STRUCTELEMENT element =
28 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), -1);
29 EXPECT_FALSE(element);
30 element = FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 1);
31 EXPECT_FALSE(element);
32 element = FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
33 ASSERT_TRUE(element);
34 EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(element));
35 EXPECT_EQ(0U, FPDF_StructElement_GetAltText(element, nullptr, 0));
36
37 ASSERT_EQ(1, FPDF_StructElement_CountChildren(element));
38 FPDF_STRUCTELEMENT child_element =
40 EXPECT_FALSE(child_element);
41 child_element = FPDF_StructElement_GetChildAtIndex(element, 1);
42 EXPECT_FALSE(child_element);
43 child_element = FPDF_StructElement_GetChildAtIndex(element, 0);
44 ASSERT_TRUE(child_element);
45 EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(child_element));
46 EXPECT_EQ(0U, FPDF_StructElement_GetAltText(child_element, nullptr, 0));
47
48 ASSERT_EQ(1, FPDF_StructElement_CountChildren(child_element));
49 FPDF_STRUCTELEMENT gchild_element =
51 EXPECT_FALSE(gchild_element);
52 gchild_element = FPDF_StructElement_GetChildAtIndex(child_element, 1);
53 EXPECT_FALSE(gchild_element);
54 gchild_element = FPDF_StructElement_GetChildAtIndex(child_element, 0);
55 ASSERT_TRUE(gchild_element);
56 EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(gchild_element));
57 ASSERT_EQ(24U, FPDF_StructElement_GetAltText(gchild_element, nullptr, 0));
58
59 unsigned short buffer[12] = {};
60 // Deliberately pass in a small buffer size to make sure |buffer| remains
61 // untouched.
62 ASSERT_EQ(24U, FPDF_StructElement_GetAltText(gchild_element, buffer, 1));
63 for (unsigned short b : buffer) {
64 EXPECT_EQ(0U, b);
65 }
66 EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(gchild_element));
67 ASSERT_EQ(24U, FPDF_StructElement_GetAltText(gchild_element, buffer,
68 sizeof(buffer)));
69 EXPECT_EQ(L"Black Image", GetPlatformWString(buffer));
70
71 ASSERT_EQ(1, FPDF_StructElement_CountChildren(gchild_element));
72 FPDF_STRUCTELEMENT ggchild_element =
74 EXPECT_FALSE(ggchild_element);
75 }
76
77 UnloadPage(page);
78}
79
81 ASSERT_TRUE(OpenDocument("tagged_actual_text.pdf"));
82 FPDF_PAGE page = LoadPage(0);
83 ASSERT_TRUE(page);
84
85 {
86 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
87 ASSERT_TRUE(struct_tree);
88 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
89
90 EXPECT_EQ(0U, FPDF_StructElement_GetActualText(nullptr, nullptr, 0));
91
92 FPDF_STRUCTELEMENT element =
93 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
94 ASSERT_TRUE(element);
95 EXPECT_EQ(0U, FPDF_StructElement_GetActualText(element, nullptr, 0));
96
97 ASSERT_EQ(1, FPDF_StructElement_CountChildren(element));
98 FPDF_STRUCTELEMENT child_element =
100 ASSERT_TRUE(child_element);
101 EXPECT_EQ(0U, FPDF_StructElement_GetActualText(child_element, nullptr, 0));
102
103 ASSERT_EQ(1, FPDF_StructElement_CountChildren(child_element));
104 FPDF_STRUCTELEMENT gchild_element =
106 ASSERT_TRUE(gchild_element);
107 ASSERT_EQ(24U,
108 FPDF_StructElement_GetActualText(gchild_element, nullptr, 0));
109
110 unsigned short buffer[12] = {};
111 // Deliberately pass in a small buffer size to make sure |buffer| remains
112 // untouched.
113 ASSERT_EQ(24U, FPDF_StructElement_GetActualText(gchild_element, buffer, 1));
114 for (unsigned short b : buffer) {
115 EXPECT_EQ(0U, b);
116 }
117 ASSERT_EQ(24U, FPDF_StructElement_GetActualText(gchild_element, buffer,
118 sizeof(buffer)));
119 EXPECT_EQ(L"Actual Text", GetPlatformWString(buffer));
120 }
121
122 UnloadPage(page);
123}
124
126 ASSERT_TRUE(OpenDocument("tagged_table.pdf"));
127 FPDF_PAGE page = LoadPage(0);
128 ASSERT_TRUE(page);
129
130 {
131 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
132 ASSERT_TRUE(struct_tree);
133 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
134
135 FPDF_STRUCTELEMENT document =
136 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
137 ASSERT_TRUE(document);
138
139 constexpr int kBufLen = 100;
140 uint16_t buffer[kBufLen] = {0};
141 EXPECT_EQ(18U, FPDF_StructElement_GetType(document, buffer, kBufLen));
142 EXPECT_EQ("Document", GetPlatformString(buffer));
143
144 ASSERT_EQ(1, FPDF_StructElement_CountChildren(document));
145 FPDF_STRUCTELEMENT table = FPDF_StructElement_GetChildAtIndex(document, 0);
146 ASSERT_TRUE(table);
147
148 EXPECT_EQ(12U, FPDF_StructElement_GetType(table, buffer, kBufLen));
149 EXPECT_EQ("Table", GetPlatformString(buffer));
150
151 // The table should have an attribute "Summary" set to the empty string.
152 EXPECT_EQ(2U, FPDF_StructElement_GetStringAttribute(table, "Summary",
153 buffer, kBufLen));
154
155 ASSERT_EQ(2, FPDF_StructElement_CountChildren(table));
156 FPDF_STRUCTELEMENT row = FPDF_StructElement_GetChildAtIndex(table, 0);
157 ASSERT_TRUE(row);
158
159 ASSERT_EQ(2, FPDF_StructElement_CountChildren(row));
160 FPDF_STRUCTELEMENT header_cell = FPDF_StructElement_GetChildAtIndex(row, 0);
161 ASSERT_TRUE(header_cell);
162
163 EXPECT_EQ(6U, FPDF_StructElement_GetType(header_cell, buffer, kBufLen));
164 EXPECT_EQ("TH", GetPlatformString(buffer));
165
166 // The header should have an attribute "Scope" with a scope of "Row".
167 EXPECT_EQ(8U, FPDF_StructElement_GetStringAttribute(header_cell, "Scope",
168 buffer, kBufLen));
169 EXPECT_EQ("Row", GetPlatformString(buffer));
170
171 // The header has an attribute "ColSpan", but it's not a string so it
172 // returns null.
173 EXPECT_EQ(0U, FPDF_StructElement_GetStringAttribute(header_cell, "ColSpan",
174 buffer, kBufLen));
175
176 // An unsupported attribute should return 0.
177 EXPECT_EQ(0U, FPDF_StructElement_GetStringAttribute(header_cell, "Other",
178 buffer, kBufLen));
179
180 // A null struct element should not crash.
181 EXPECT_EQ(0U, FPDF_StructElement_GetStringAttribute(nullptr, "Other",
182 buffer, kBufLen));
183 }
184
185 UnloadPage(page);
186}
187
189 ASSERT_TRUE(OpenDocument("tagged_table_bad_elem.pdf"));
190 FPDF_PAGE page = LoadPage(0);
191 ASSERT_TRUE(page);
192
193 {
194 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
195 ASSERT_TRUE(struct_tree);
196 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
197
198 FPDF_STRUCTELEMENT document =
199 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
200 ASSERT_TRUE(document);
201
202 constexpr int kBufLen = 100;
203 uint16_t buffer[kBufLen] = {0};
204 EXPECT_EQ(18U, FPDF_StructElement_GetType(document, buffer, kBufLen));
205 EXPECT_EQ("Document", GetPlatformString(buffer));
206
207 // The table can be retrieved, even though it does not have /Type.
208 ASSERT_EQ(1, FPDF_StructElement_CountChildren(document));
209 FPDF_STRUCTELEMENT table = FPDF_StructElement_GetChildAtIndex(document, 0);
210 ASSERT_TRUE(table);
211
212 EXPECT_EQ(12U, FPDF_StructElement_GetType(table, buffer, kBufLen));
213 EXPECT_EQ("Table", GetPlatformString(buffer));
214
215 // The table entry cannot be retrieved, as the element is malformed.
216 EXPECT_EQ(0U, FPDF_StructElement_GetStringAttribute(table, "Summary",
217 buffer, kBufLen));
218
219 // The row can be retrieved, even though it had an invalid /Type.
220 ASSERT_EQ(1, FPDF_StructElement_CountChildren(table));
221 FPDF_STRUCTELEMENT row = FPDF_StructElement_GetChildAtIndex(table, 0);
222 EXPECT_TRUE(row);
223 }
224
225 UnloadPage(page);
226}
227
229 ASSERT_TRUE(OpenDocument("tagged_table.pdf"));
230 FPDF_PAGE page = LoadPage(0);
231 ASSERT_TRUE(page);
232
233 {
234 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
235 ASSERT_TRUE(struct_tree);
236 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
237
238 FPDF_STRUCTELEMENT document =
239 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
240 ASSERT_TRUE(document);
241
242 constexpr int kBufLen = 100;
243 uint16_t buffer[kBufLen] = {0};
244 EXPECT_EQ(18U, FPDF_StructElement_GetType(document, buffer, kBufLen));
245 EXPECT_EQ("Document", GetPlatformString(buffer));
246
247 // The document has no ID.
248 EXPECT_EQ(0U, FPDF_StructElement_GetID(document, buffer, kBufLen));
249
250 ASSERT_EQ(1, FPDF_StructElement_CountChildren(document));
251 FPDF_STRUCTELEMENT table = FPDF_StructElement_GetChildAtIndex(document, 0);
252 ASSERT_TRUE(table);
253
254 EXPECT_EQ(12U, FPDF_StructElement_GetType(table, buffer, kBufLen));
255 EXPECT_EQ("Table", GetPlatformString(buffer));
256
257 // The table has an ID.
258 EXPECT_EQ(14U, FPDF_StructElement_GetID(table, buffer, kBufLen));
259 EXPECT_EQ("node12", GetPlatformString(buffer));
260
261 // The first child of the table is a row, which has an empty ID.
262 // It returns 2U, the length of an empty string, instead of 0U,
263 // representing null.
264 ASSERT_EQ(2, FPDF_StructElement_CountChildren(table));
265 FPDF_STRUCTELEMENT row = FPDF_StructElement_GetChildAtIndex(table, 0);
266 ASSERT_TRUE(row);
267 EXPECT_EQ(2U, FPDF_StructElement_GetID(row, buffer, kBufLen));
268 }
269
270 UnloadPage(page);
271}
272
274 ASSERT_TRUE(OpenDocument("tagged_table.pdf"));
275 FPDF_PAGE page = LoadPage(0);
276 ASSERT_TRUE(page);
277
278 {
279 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
280 ASSERT_TRUE(struct_tree);
281 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
282
283 FPDF_STRUCTELEMENT document =
284 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
285 ASSERT_TRUE(document);
286
287 constexpr int kBufLen = 100;
288 uint16_t buffer[kBufLen] = {0};
289 EXPECT_EQ(18U, FPDF_StructElement_GetType(document, buffer, kBufLen));
290 EXPECT_EQ("Document", GetPlatformString(buffer));
291
292 // Nullptr test
293 EXPECT_EQ(0U, FPDF_StructElement_GetLang(nullptr, buffer, kBufLen));
294
295 // The document has a language.
296 EXPECT_EQ(12U, FPDF_StructElement_GetLang(document, buffer, kBufLen));
297 EXPECT_EQ("en-US", GetPlatformString(buffer));
298
299 ASSERT_EQ(1, FPDF_StructElement_CountChildren(document));
300 FPDF_STRUCTELEMENT table = FPDF_StructElement_GetChildAtIndex(document, 0);
301 ASSERT_TRUE(table);
302
303 // The first child is a table, with a language.
304 EXPECT_EQ(12U, FPDF_StructElement_GetType(table, buffer, kBufLen));
305 EXPECT_EQ("Table", GetPlatformString(buffer));
306
307 EXPECT_EQ(6U, FPDF_StructElement_GetLang(table, buffer, kBufLen));
308 EXPECT_EQ("hu", GetPlatformString(buffer));
309
310 // The first child of the table is a row, which doesn't have a
311 // language explicitly set on it.
312 ASSERT_EQ(2, FPDF_StructElement_CountChildren(table));
313 FPDF_STRUCTELEMENT row = FPDF_StructElement_GetChildAtIndex(table, 0);
314 ASSERT_TRUE(row);
315 EXPECT_EQ(0U, FPDF_StructElement_GetLang(row, buffer, kBufLen));
316 }
317
318 UnloadPage(page);
319}
320
321// See also FPDFEditEmbedderTest.TraverseMarkedContentID, which traverses the
322// marked contents using FPDFPageObj_GetMark() and related API.
324 ASSERT_TRUE(OpenDocument("marked_content_id.pdf"));
325 FPDF_PAGE page = LoadPage(0);
326 ASSERT_TRUE(page);
327
328 {
329 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
330 ASSERT_TRUE(struct_tree);
331 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
332
333 FPDF_STRUCTELEMENT element =
334 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
335 EXPECT_EQ(0, FPDF_StructElement_GetMarkedContentID(element));
336 }
337
338 UnloadPage(page);
339}
340
342 ASSERT_TRUE(OpenDocument("tagged_marked_content.pdf"));
343 FPDF_PAGE page = LoadPage(0);
344 ASSERT_TRUE(page);
345
346 {
347 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
348 ASSERT_TRUE(struct_tree);
349 ASSERT_EQ(4, FPDF_StructTree_CountChildren(struct_tree.get()));
350
351 // K is an integer MCID
352 FPDF_STRUCTELEMENT child1 =
353 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
354 ASSERT_TRUE(child1);
355 // Legacy API
356 EXPECT_EQ(0, FPDF_StructElement_GetMarkedContentID(child1));
357
358 // K is a dict containing MCR object reference
359 FPDF_STRUCTELEMENT child2 =
360 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 1);
361 ASSERT_TRUE(child2);
362
363 // K is an array containing dict MCR object reference and integer MCID
364 FPDF_STRUCTELEMENT child3 =
365 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 2);
366 ASSERT_TRUE(child3);
367
368 // K does not exist
369 FPDF_STRUCTELEMENT child4 =
370 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 3);
371 ASSERT_TRUE(child4);
372
373 // New APIs
380
383
387
390 }
391
392 UnloadPage(page);
393}
394
396 ASSERT_TRUE(OpenDocument("tagged_mcr_multipage.pdf"));
397
398 // Using the loop to make difference clear
399 for (int page_i : {0, 1}) {
400 FPDF_PAGE page = LoadPage(page_i);
401 ASSERT_TRUE(page);
402 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
403 ASSERT_TRUE(struct_tree);
404 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
405
406 FPDF_STRUCTELEMENT struct_doc =
407 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
408 ASSERT_TRUE(struct_doc);
409 EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(struct_doc));
410
411 ASSERT_EQ(2, FPDF_StructElement_CountChildren(struct_doc));
412 FPDF_STRUCTELEMENT child1 =
413 FPDF_StructElement_GetChildAtIndex(struct_doc, 0);
414 EXPECT_FALSE(child1);
415 FPDF_STRUCTELEMENT child2 =
416 FPDF_StructElement_GetChildAtIndex(struct_doc, 1);
417 EXPECT_FALSE(child2);
418
419 EXPECT_EQ(2, FPDF_StructElement_GetMarkedContentIdCount(struct_doc));
420
421 // Both MCID are returned as if part of this page, while they are not.
422 // So `FPDF_StructElement_GetMarkedContentIdAtIndex(...)` does not work
423 // for StructElement spanning multiple pages.
424 EXPECT_EQ(0, FPDF_StructElement_GetMarkedContentIdAtIndex(struct_doc, 0));
425 EXPECT_EQ(0, FPDF_StructElement_GetMarkedContentIdAtIndex(struct_doc, 1));
426
427 // One MCR is pointing to page 1, another to page2, so those are different
428 // for different pages.
429 EXPECT_EQ(page_i == 0 ? 0 : -1,
430 FPDF_StructElement_GetChildMarkedContentID(struct_doc, 0));
431 EXPECT_EQ(page_i == 1 ? 0 : -1,
432 FPDF_StructElement_GetChildMarkedContentID(struct_doc, 1));
433 // Invalid index
434 EXPECT_EQ(-1, FPDF_StructElement_GetChildMarkedContentID(struct_doc, -1));
435 EXPECT_EQ(-1, FPDF_StructElement_GetChildMarkedContentID(struct_doc, 2));
436 // Invalid element
437 EXPECT_EQ(-1, FPDF_StructElement_GetChildMarkedContentID(nullptr, 0));
438 UnloadPage(page);
439 }
440}
441
443 ASSERT_TRUE(OpenDocument("tagged_alt_text.pdf"));
444 FPDF_PAGE page = LoadPage(0);
445 ASSERT_TRUE(page);
446
447 {
448 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
449 ASSERT_TRUE(struct_tree);
450 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
451
452 FPDF_STRUCTELEMENT element =
453 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
454 ASSERT_TRUE(element);
455
456 // test nullptr inputs
457 unsigned short buffer[12] = {};
458 ASSERT_EQ(0U, FPDF_StructElement_GetType(nullptr, buffer, sizeof(buffer)));
459 ASSERT_EQ(0U, FPDF_StructElement_GetType(nullptr, nullptr, 0));
460 ASSERT_EQ(18U, FPDF_StructElement_GetType(element, nullptr, 0));
461
462 // Deliberately pass in a small buffer size to make sure |buffer| remains
463 // untouched.
464 fxcrt::Fill(buffer, 0xbdfcu);
465 ASSERT_EQ(18U, FPDF_StructElement_GetType(element, buffer, 1));
466 for (const auto b : buffer) {
467 EXPECT_EQ(0xbdfcu, b);
468 }
469 ASSERT_EQ(18U, FPDF_StructElement_GetType(element, buffer, sizeof(buffer)));
470 EXPECT_EQ(L"Document", GetPlatformWString(buffer));
471 }
472
473 UnloadPage(page);
474}
475
477 ASSERT_TRUE(OpenDocument("tagged_table_bad_elem.pdf"));
478 FPDF_PAGE page = LoadPage(0);
479 ASSERT_TRUE(page);
480
481 {
482 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
483 ASSERT_TRUE(struct_tree);
484 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
485
486 FPDF_STRUCTELEMENT child =
487 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
488 ASSERT_TRUE(child);
489
490 // test nullptr inputs
491 unsigned short buffer[28] = {};
492 ASSERT_EQ(0U,
493 FPDF_StructElement_GetObjType(nullptr, buffer, sizeof(buffer)));
494 ASSERT_EQ(0U, FPDF_StructElement_GetObjType(nullptr, nullptr, 0));
495 ASSERT_EQ(22U, FPDF_StructElement_GetObjType(child, nullptr, 0));
496
497 // Deliberately pass in a small buffer size to make sure `buffer` remains
498 // untouched.
499 ASSERT_EQ(22U, FPDF_StructElement_GetObjType(child, buffer, 1));
500 for (unsigned short b : buffer) {
501 EXPECT_EQ(0U, b);
502 }
503 ASSERT_EQ(22U,
504 FPDF_StructElement_GetObjType(child, buffer, sizeof(buffer)));
505 EXPECT_EQ(L"StructElem", GetPlatformWString(buffer));
506
507 ASSERT_EQ(1, FPDF_StructElement_CountChildren(child));
508 FPDF_STRUCTELEMENT gchild = FPDF_StructElement_GetChildAtIndex(child, 0);
509
510 fxcrt::Fill(buffer, 0xbdfcu);
511 // Missing /Type in `gchild`
512 ASSERT_EQ(0U,
513 FPDF_StructElement_GetObjType(gchild, buffer, sizeof(buffer)));
514 // Buffer is untouched.
515 for (const auto b : buffer) {
516 EXPECT_EQ(0xbdfcu, b);
517 }
518 ASSERT_EQ(1, FPDF_StructElement_CountChildren(gchild));
519 FPDF_STRUCTELEMENT ggchild = FPDF_StructElement_GetChildAtIndex(gchild, 0);
520 ASSERT_EQ(28U,
521 FPDF_StructElement_GetObjType(ggchild, buffer, sizeof(buffer)));
522 // Reading bad elem also works.
523 EXPECT_EQ(L"NotStructElem", GetPlatformWString(buffer));
524 }
525
526 UnloadPage(page);
527}
528
530 ASSERT_TRUE(OpenDocument("tagged_alt_text.pdf"));
531 FPDF_PAGE page = LoadPage(0);
532 ASSERT_TRUE(page);
533
534 {
535 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
536 ASSERT_TRUE(struct_tree);
537 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
538
539 FPDF_STRUCTELEMENT parent =
540 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
541 ASSERT_TRUE(parent);
542
543 ASSERT_EQ(1, FPDF_StructElement_CountChildren(parent));
544
545 FPDF_STRUCTELEMENT child = FPDF_StructElement_GetChildAtIndex(parent, 0);
546 ASSERT_TRUE(child);
547
548 // test nullptr inputs
549 ASSERT_EQ(nullptr, FPDF_StructElement_GetParent(nullptr));
550
551 ASSERT_EQ(parent, FPDF_StructElement_GetParent(child));
552
553 // The parent of `parent` is StructTreeRoot and no longer a StructElement.
554 // We currently handle this case by returning a nullptr.
555 ASSERT_EQ(nullptr, FPDF_StructElement_GetParent(parent));
556 }
557
558 UnloadPage(page);
559}
560
562 ASSERT_TRUE(OpenDocument("tagged_alt_text.pdf"));
563 FPDF_PAGE page = LoadPage(0);
564 ASSERT_TRUE(page);
565
566 {
567 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
568 ASSERT_TRUE(struct_tree);
569 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
570
571 FPDF_STRUCTELEMENT element =
572 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
573 ASSERT_TRUE(element);
574
575 // test nullptr inputs
576 unsigned short buffer[13] = {};
577 ASSERT_EQ(0U, FPDF_StructElement_GetTitle(nullptr, buffer, sizeof(buffer)));
578 ASSERT_EQ(0U, FPDF_StructElement_GetTitle(nullptr, nullptr, 0));
579 ASSERT_EQ(20U, FPDF_StructElement_GetTitle(element, nullptr, 0));
580
581 // Deliberately pass in a small buffer size to make sure |buffer| remains
582 // untouched.
583 fxcrt::Fill(buffer, 0xbdfcu);
584 ASSERT_EQ(20U, FPDF_StructElement_GetTitle(element, buffer, 1));
585 for (const auto b : buffer) {
586 EXPECT_EQ(0xbdfcu, b);
587 }
588
589 ASSERT_EQ(20U,
590 FPDF_StructElement_GetTitle(element, buffer, sizeof(buffer)));
591 EXPECT_EQ(L"TitleText", GetPlatformWString(buffer));
592
593 ASSERT_EQ(1, FPDF_StructElement_CountChildren(element));
594 FPDF_STRUCTELEMENT child_element =
596 ASSERT_TRUE(element);
597
598 ASSERT_EQ(26U, FPDF_StructElement_GetTitle(child_element, buffer,
599 sizeof(buffer)));
600 EXPECT_EQ(L"symbol: 100k", GetPlatformWString(buffer));
601 }
602
603 UnloadPage(page);
604}
605
607 ASSERT_TRUE(OpenDocument("tagged_table.pdf"));
608 FPDF_PAGE page = LoadPage(0);
609 ASSERT_TRUE(page);
610
611 {
612 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
613 ASSERT_TRUE(struct_tree);
614 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
615
616 FPDF_STRUCTELEMENT document =
617 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
618 ASSERT_TRUE(document);
619
620 ASSERT_EQ(1, FPDF_StructElement_CountChildren(document));
621 ASSERT_EQ(-1, FPDF_StructElement_GetAttributeCount(document));
622 FPDF_STRUCTELEMENT table = FPDF_StructElement_GetChildAtIndex(document, 0);
623 ASSERT_TRUE(table);
624
625 ASSERT_EQ(2, FPDF_StructElement_CountChildren(table));
626
627 {
628 FPDF_STRUCTELEMENT tr = FPDF_StructElement_GetChildAtIndex(table, 0);
629 ASSERT_TRUE(tr);
630
632 FPDF_STRUCTELEMENT th = FPDF_StructElement_GetChildAtIndex(tr, 0);
633 ASSERT_TRUE(th);
634
636
637 // nullptr test
638 ASSERT_EQ(nullptr, FPDF_StructElement_GetAttributeAtIndex(document, 0));
639 ASSERT_EQ(nullptr, FPDF_StructElement_GetAttributeAtIndex(document, -1));
640 ASSERT_EQ(nullptr, FPDF_StructElement_GetAttributeAtIndex(th, 2));
641
642 FPDF_STRUCTELEMENT_ATTR attr =
644 ASSERT_TRUE(attr);
645
646 ASSERT_EQ(2, FPDF_StructElement_Attr_GetCount(attr));
647 ASSERT_FALSE(
648 FPDF_StructElement_Attr_GetName(attr, 1, nullptr, 0U, nullptr));
649 unsigned long buffer_len_needed = ULONG_MAX;
650 // Pass buffer = nullptr to obtain the size of the buffer needed,
651 ASSERT_TRUE(FPDF_StructElement_Attr_GetName(attr, 1, nullptr, 0,
652 &buffer_len_needed));
653 EXPECT_EQ(2U, buffer_len_needed);
654 char buffer[8] = {};
655 unsigned long out_len = ULONG_MAX;
656 // Deliberately pass in a small buffer size to make sure `buffer` remains
657 // untouched.
658 ASSERT_TRUE(
659 FPDF_StructElement_Attr_GetName(attr, 1, buffer, 1, &out_len));
660 EXPECT_EQ(2U, out_len);
661 for (unsigned short b : buffer) {
662 EXPECT_EQ(0U, b);
663 }
664 ASSERT_TRUE(FPDF_StructElement_Attr_GetName(attr, 1, buffer,
665 sizeof(buffer), &out_len));
666 EXPECT_EQ(2U, out_len);
667 EXPECT_STREQ("O", buffer);
668
669 // Make sure bad inputs do not work.
670 EXPECT_FALSE(FPDF_StructElement_Attr_GetValue(nullptr, ""));
671 EXPECT_FALSE(FPDF_StructElement_Attr_GetValue(attr, "DOES_NOT_EXIST"));
672 EXPECT_FALSE(FPDF_StructElement_Attr_GetValue(attr, "DOES_NOT_EXIST"));
673
674 FPDF_STRUCTELEMENT_ATTR_VALUE attr_value =
676 ASSERT_TRUE(attr_value);
677
679
680 unsigned short str_val[12] = {};
682 attr_value, str_val, sizeof(str_val), &out_len));
683 EXPECT_EQ(12U, out_len);
684 EXPECT_EQ(L"Table", GetPlatformWString(str_val));
685
686 fxcrt::Fill(buffer, 0u);
687 ASSERT_TRUE(FPDF_StructElement_Attr_GetName(attr, 0, buffer,
688 sizeof(buffer), &out_len));
689 EXPECT_EQ(8U, out_len);
690 EXPECT_STREQ("ColSpan", buffer);
691 attr_value = FPDF_StructElement_Attr_GetValue(attr, buffer);
692 ASSERT_TRUE(attr_value);
693 EXPECT_EQ(FPDF_OBJECT_NUMBER,
695 float num_val;
696 ASSERT_TRUE(FPDF_StructElement_Attr_GetNumberValue(attr_value, &num_val));
697 EXPECT_FLOAT_EQ(2.0f, num_val);
698 }
699
700 {
701 FPDF_STRUCTELEMENT tr = FPDF_StructElement_GetChildAtIndex(table, 1);
702 ASSERT_TRUE(tr);
703
705 // nullptr when index out of range
706 ASSERT_EQ(nullptr, FPDF_StructElement_GetAttributeAtIndex(tr, 1));
707
709 FPDF_STRUCTELEMENT td = FPDF_StructElement_GetChildAtIndex(tr, 1);
710 ASSERT_TRUE(td);
711 {
712 // Test counting and obtaining attributes via reference
714 FPDF_STRUCTELEMENT_ATTR attr =
716 ASSERT_TRUE(attr);
717 ASSERT_EQ(4, FPDF_StructElement_Attr_GetCount(attr));
718 // Test string and blob type
719 {
720 char buffer[16] = {};
721 unsigned long out_len = ULONG_MAX;
723 attr, 0, buffer, sizeof(buffer), &out_len));
724 EXPECT_EQ(8U, out_len);
725 EXPECT_STREQ("ColProp", buffer);
726
727 FPDF_STRUCTELEMENT_ATTR_VALUE attr_value =
729 ASSERT_TRUE(attr_value);
730 EXPECT_EQ(FPDF_OBJECT_STRING,
732
733 unsigned short str_val[12] = {};
735 attr_value, str_val, sizeof(str_val), &out_len));
736 EXPECT_EQ(8U, out_len);
737 EXPECT_EQ(L"Sum", GetPlatformWString(str_val));
738
739 char blob_val[3] = {};
741 attr_value, blob_val, sizeof(blob_val), &out_len));
742 EXPECT_EQ(3U, out_len);
743 EXPECT_EQ('S', blob_val[0]);
744 EXPECT_EQ('u', blob_val[1]);
745 EXPECT_EQ('m', blob_val[2]);
746 }
747
748 // Test boolean type
749 {
750 char buffer[16] = {};
751 unsigned long out_len = ULONG_MAX;
753 attr, 1, buffer, sizeof(buffer), &out_len));
754 EXPECT_EQ(7U, out_len);
755 EXPECT_STREQ("CurUSD", buffer);
756
757 FPDF_STRUCTELEMENT_ATTR_VALUE attr_value =
759 ASSERT_TRUE(attr_value);
760 EXPECT_EQ(FPDF_OBJECT_BOOLEAN,
762 FPDF_BOOL val;
763 ASSERT_TRUE(
765 EXPECT_TRUE(val);
766 }
767
768 // Test reference to number
769 {
770 char buffer[16] = {};
771 unsigned long out_len = ULONG_MAX;
773 attr, 3, buffer, sizeof(buffer), &out_len));
774 EXPECT_EQ(8U, out_len);
775 EXPECT_STREQ("RowSpan", buffer);
776
777 FPDF_STRUCTELEMENT_ATTR_VALUE attr_value =
779 ASSERT_TRUE(attr_value);
780 EXPECT_EQ(FPDF_OBJECT_NUMBER,
782 float val;
783 ASSERT_TRUE(FPDF_StructElement_Attr_GetNumberValue(attr_value, &val));
784 EXPECT_FLOAT_EQ(3, val);
785 }
786 }
787 }
788 }
789
790 UnloadPage(page);
791}
792
794 ASSERT_TRUE(OpenDocument("tagged_actual_text.pdf"));
795 FPDF_PAGE page = LoadPage(0);
796 ASSERT_TRUE(page);
797
798 {
799 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
800 ASSERT_TRUE(struct_tree);
801 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
802
803 FPDF_STRUCTELEMENT element =
804 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
805 ASSERT_TRUE(element);
806 ASSERT_EQ(1, FPDF_StructElement_CountChildren(element));
807
808 FPDF_STRUCTELEMENT child_element =
810 ASSERT_TRUE(child_element);
811 ASSERT_EQ(1, FPDF_StructElement_CountChildren(child_element));
812
813 FPDF_STRUCTELEMENT gchild_element =
815 ASSERT_TRUE(gchild_element);
816
817 int gchild_attr_count =
819 ASSERT_EQ(1, gchild_attr_count);
820
821 FPDF_STRUCTELEMENT_ATTR attr =
823 ASSERT_TRUE(attr);
824
825 int attr_count = FPDF_StructElement_Attr_GetCount(attr);
826 ASSERT_EQ(5, attr_count);
827
828 char name[20] = {};
829 unsigned long required_len;
830 ASSERT_TRUE(FPDF_StructElement_Attr_GetName(attr, 1, name, sizeof(name),
831 &required_len));
832 EXPECT_EQ(7u, required_len);
833 EXPECT_STREQ("Height", name);
834
835 // Reject bad values for FPDF_StructElement_Attr_CountChildren().
836 EXPECT_EQ(-1, FPDF_StructElement_Attr_CountChildren(nullptr));
837 EXPECT_FALSE(FPDF_StructElement_Attr_GetChildAtIndex(nullptr, -1));
838 EXPECT_FALSE(FPDF_StructElement_Attr_GetChildAtIndex(nullptr, 0));
839 EXPECT_FALSE(FPDF_StructElement_Attr_GetChildAtIndex(nullptr, 1));
840 {
841 FPDF_STRUCTELEMENT_ATTR_VALUE attr_value =
843 ASSERT_TRUE(attr_value);
844 EXPECT_EQ(FPDF_OBJECT_NUMBER,
846 EXPECT_EQ(-1, FPDF_StructElement_Attr_CountChildren(attr_value));
847 EXPECT_FALSE(FPDF_StructElement_Attr_GetChildAtIndex(attr_value, -1));
848 EXPECT_FALSE(FPDF_StructElement_Attr_GetChildAtIndex(attr_value, 0));
849 EXPECT_FALSE(FPDF_StructElement_Attr_GetChildAtIndex(attr_value, 1));
850 }
851
852 ASSERT_TRUE(FPDF_StructElement_Attr_GetName(attr, 0, name, sizeof(name),
853 &required_len));
854 EXPECT_EQ(5u, required_len);
855 EXPECT_STREQ("BBox", name);
856
857 FPDF_STRUCTELEMENT_ATTR_VALUE attr_value =
859 ASSERT_TRUE(attr_value);
861 EXPECT_EQ(4, FPDF_StructElement_Attr_CountChildren(attr_value));
862 FPDF_STRUCTELEMENT_ATTR_VALUE nested_attr_value0 =
864 ASSERT_TRUE(nested_attr_value0);
865 EXPECT_EQ(FPDF_OBJECT_NUMBER,
866 FPDF_StructElement_Attr_GetType(nested_attr_value0));
867 FPDF_STRUCTELEMENT_ATTR_VALUE nested_attr_value3 =
869 ASSERT_TRUE(nested_attr_value3);
870 EXPECT_EQ(FPDF_OBJECT_NUMBER,
871 FPDF_StructElement_Attr_GetType(nested_attr_value3));
872 }
873
874 UnloadPage(page);
875}
876
878 ASSERT_TRUE(OpenDocument("tagged_nested.pdf"));
879 FPDF_PAGE page = LoadPage(0);
880 ASSERT_TRUE(page);
881
882 {
883 // This call should not crash. https://crbug.com/pdfium/1480
884 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
885 ASSERT_TRUE(struct_tree);
886 }
887 UnloadPage(page);
888}
889
891 ASSERT_TRUE(OpenDocument("tagged_mcr_objr.pdf"));
892 FPDF_PAGE page = LoadPage(0);
893 ASSERT_TRUE(page);
894
895 {
896 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
897 ASSERT_TRUE(struct_tree);
898 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
899
900 FPDF_STRUCTELEMENT object8 =
901 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
902 ASSERT_TRUE(object8);
903 unsigned short buffer[12];
904 ASSERT_EQ(18U, FPDF_StructElement_GetType(object8, buffer, sizeof(buffer)));
905 EXPECT_EQ(L"Document", GetPlatformWString(buffer));
906 EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(object8));
907 ASSERT_EQ(2, FPDF_StructElement_CountChildren(object8));
908
909 // First branch. 10 -> 12 -> 13 -> Inline dict.
910 FPDF_STRUCTELEMENT object10 =
912 ASSERT_TRUE(object10);
913 ASSERT_EQ(20U,
914 FPDF_StructElement_GetType(object10, buffer, sizeof(buffer)));
915 EXPECT_EQ(L"NonStruct", GetPlatformWString(buffer));
916 EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(object10));
917 ASSERT_EQ(1, FPDF_StructElement_CountChildren(object10));
918
919 FPDF_STRUCTELEMENT object12 =
921 ASSERT_TRUE(object12);
922 ASSERT_EQ(4U, FPDF_StructElement_GetType(object12, buffer, sizeof(buffer)));
923 EXPECT_EQ(L"P", GetPlatformWString(buffer));
924 EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(object12));
925 ASSERT_EQ(1, FPDF_StructElement_CountChildren(object12));
926
927 FPDF_STRUCTELEMENT object13 =
929 ASSERT_TRUE(object13);
930 ASSERT_EQ(20U,
931 FPDF_StructElement_GetType(object13, buffer, sizeof(buffer)));
932 EXPECT_EQ(L"NonStruct", GetPlatformWString(buffer));
933 EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(object13));
934 ASSERT_EQ(1, FPDF_StructElement_CountChildren(object13));
935
936 // TODO(crbug.com/pdfium/672): Fetch this child element.
937 EXPECT_FALSE(FPDF_StructElement_GetChildAtIndex(object13, 0));
938
939 // Second branch. 11 -> 14 -> Inline dict.
940 // -> 15 -> Inline dict.
941 FPDF_STRUCTELEMENT object11 =
943 ASSERT_TRUE(object11);
944 ASSERT_EQ(4U, FPDF_StructElement_GetType(object11, buffer, sizeof(buffer)));
945 EXPECT_EQ(L"P", GetPlatformWString(buffer));
946 EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(object11));
947 ASSERT_EQ(1, FPDF_StructElement_CountChildren(object11));
948
949 FPDF_STRUCTELEMENT object14 =
951 ASSERT_TRUE(object14);
952 ASSERT_EQ(20U,
953 FPDF_StructElement_GetType(object14, buffer, sizeof(buffer)));
954 EXPECT_EQ(L"NonStruct", GetPlatformWString(buffer));
955 EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(object14));
956 ASSERT_EQ(2, FPDF_StructElement_CountChildren(object14));
957
958 // TODO(crbug.com/pdfium/672): Object 15 should be at index 1.
959 EXPECT_FALSE(FPDF_StructElement_GetChildAtIndex(object14, 1));
960 FPDF_STRUCTELEMENT object15 =
962 ASSERT_TRUE(object15);
963 ASSERT_EQ(20U,
964 FPDF_StructElement_GetType(object15, buffer, sizeof(buffer)));
965 EXPECT_EQ(L"NonStruct", GetPlatformWString(buffer));
966 EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(object15));
967 ASSERT_EQ(1, FPDF_StructElement_CountChildren(object15));
968
969 // TODO(crbug.com/pdfium/672): Fetch this child element.
970 EXPECT_FALSE(FPDF_StructElement_GetChildAtIndex(object15, 0));
971 }
972
973 UnloadPage(page);
974}
975
977 ASSERT_TRUE(OpenDocument("bug_1768.pdf"));
978 FPDF_PAGE page = LoadPage(0);
979 ASSERT_TRUE(page);
980
981 {
982 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
983 ASSERT_TRUE(struct_tree);
984 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
985
986 // TODO(crbug.com/pdfium/1768): Fetch this child element. Then consider
987 // writing more of the test to make sure other elements in the tree can be
988 // fetched correctly as well.
989 EXPECT_FALSE(FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0));
990 }
991
992 UnloadPage(page);
993}
994
996 ASSERT_TRUE(OpenDocument("bug_1296920.pdf"));
997 FPDF_PAGE page = LoadPage(0);
998 ASSERT_TRUE(page);
999
1000 {
1001 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
1002 ASSERT_TRUE(struct_tree);
1003 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
1004
1005 // Destroying this tree should not crash.
1006 }
1007
1008 UnloadPage(page);
1009}
1010
1012 ASSERT_TRUE(OpenDocument("tagged_table_bad_parent.pdf"));
1013 FPDF_PAGE page = LoadPage(0);
1014 ASSERT_TRUE(page);
1015
1016 {
1017 // Calling these APIs should not trigger a dangling pointer.
1018 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
1019 ASSERT_TRUE(struct_tree);
1020 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
1021 }
1022
1023 UnloadPage(page);
1024}
FPDF_EXPORT FPDF_STRUCTELEMENT FPDF_CALLCONV FPDF_StructElement_GetParent(FPDF_STRUCTELEMENT struct_element)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDF_StructElement_GetLang(FPDF_STRUCTELEMENT struct_element, void *buffer, unsigned long buflen)
FPDF_EXPORT int FPDF_CALLCONV FPDF_StructElement_GetAttributeCount(FPDF_STRUCTELEMENT struct_element)
FPDF_EXPORT FPDF_STRUCTTREE FPDF_CALLCONV FPDF_StructTree_GetForPage(FPDF_PAGE page)
FPDF_EXPORT int FPDF_CALLCONV FPDF_StructElement_GetMarkedContentID(FPDF_STRUCTELEMENT struct_element)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDF_StructElement_GetStringAttribute(FPDF_STRUCTELEMENT struct_element, FPDF_BYTESTRING attr_name, void *buffer, unsigned long buflen)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDF_StructElement_Attr_GetName(FPDF_STRUCTELEMENT_ATTR struct_attribute, int index, void *buffer, unsigned long buflen, unsigned long *out_buflen)
FPDF_EXPORT FPDF_STRUCTELEMENT_ATTR_VALUE FPDF_CALLCONV FPDF_StructElement_Attr_GetChildAtIndex(FPDF_STRUCTELEMENT_ATTR_VALUE value, int index)
FPDF_EXPORT int FPDF_CALLCONV FPDF_StructElement_GetMarkedContentIdAtIndex(FPDF_STRUCTELEMENT struct_element, int index)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDF_StructElement_GetActualText(FPDF_STRUCTELEMENT struct_element, void *buffer, unsigned long buflen)
FPDF_EXPORT int FPDF_CALLCONV FPDF_StructElement_Attr_GetCount(FPDF_STRUCTELEMENT_ATTR struct_attribute)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDF_StructElement_GetID(FPDF_STRUCTELEMENT struct_element, void *buffer, unsigned long buflen)
FPDF_EXPORT FPDF_OBJECT_TYPE FPDF_CALLCONV FPDF_StructElement_Attr_GetType(FPDF_STRUCTELEMENT_ATTR_VALUE value)
FPDF_EXPORT FPDF_STRUCTELEMENT_ATTR_VALUE FPDF_CALLCONV FPDF_StructElement_Attr_GetValue(FPDF_STRUCTELEMENT_ATTR struct_attribute, FPDF_BYTESTRING name)
FPDF_EXPORT FPDF_STRUCTELEMENT FPDF_CALLCONV FPDF_StructElement_GetChildAtIndex(FPDF_STRUCTELEMENT struct_element, int index)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDF_StructElement_Attr_GetNumberValue(FPDF_STRUCTELEMENT_ATTR_VALUE value, float *out_value)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDF_StructElement_GetObjType(FPDF_STRUCTELEMENT struct_element, void *buffer, unsigned long buflen)
FPDF_EXPORT FPDF_STRUCTELEMENT_ATTR FPDF_CALLCONV FPDF_StructElement_GetAttributeAtIndex(FPDF_STRUCTELEMENT struct_element, int index)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDF_StructElement_Attr_GetBlobValue(FPDF_STRUCTELEMENT_ATTR_VALUE value, void *buffer, unsigned long buflen, unsigned long *out_buflen)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDF_StructElement_Attr_GetStringValue(FPDF_STRUCTELEMENT_ATTR_VALUE value, void *buffer, unsigned long buflen, unsigned long *out_buflen)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDF_StructElement_GetType(FPDF_STRUCTELEMENT struct_element, void *buffer, unsigned long buflen)
FPDF_EXPORT int FPDF_CALLCONV FPDF_StructElement_Attr_CountChildren(FPDF_STRUCTELEMENT_ATTR_VALUE value)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDF_StructElement_GetAltText(FPDF_STRUCTELEMENT struct_element, void *buffer, unsigned long buflen)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDF_StructElement_Attr_GetBooleanValue(FPDF_STRUCTELEMENT_ATTR_VALUE value, FPDF_BOOL *out_value)
FPDF_EXPORT int FPDF_CALLCONV FPDF_StructElement_CountChildren(FPDF_STRUCTELEMENT struct_element)
FPDF_EXPORT int FPDF_CALLCONV FPDF_StructElement_GetMarkedContentIdCount(FPDF_STRUCTELEMENT struct_element)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDF_StructElement_GetTitle(FPDF_STRUCTELEMENT struct_element, void *buffer, unsigned long buflen)
TEST_F(FPDFStructTreeEmbedderTest, GetAltText)
#define FPDF_OBJECT_NUMBER
Definition fpdfview.h:38
#define FPDF_OBJECT_NAME
Definition fpdfview.h:40
#define FPDF_OBJECT_BOOLEAN
Definition fpdfview.h:37
#define FPDF_OBJECT_STRING
Definition fpdfview.h:39
#define FPDF_OBJECT_ARRAY
Definition fpdfview.h:41
std::string GetPlatformString(FPDF_WIDESTRING wstr)
std::wstring GetPlatformWString(FPDF_WIDESTRING wstr)