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"
18 ASSERT_TRUE(OpenDocument(
"tagged_alt_text.pdf"));
19 FPDF_PAGE page = LoadPage(0);
24 ASSERT_TRUE(struct_tree);
25 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
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);
38 FPDF_STRUCTELEMENT child_element =
40 EXPECT_FALSE(child_element);
42 EXPECT_FALSE(child_element);
44 ASSERT_TRUE(child_element);
49 FPDF_STRUCTELEMENT gchild_element =
51 EXPECT_FALSE(gchild_element);
53 EXPECT_FALSE(gchild_element);
55 ASSERT_TRUE(gchild_element);
59 unsigned short buffer[12] = {};
63 for (
unsigned short b : buffer) {
72 FPDF_STRUCTELEMENT ggchild_element =
74 EXPECT_FALSE(ggchild_element);
81 ASSERT_TRUE(OpenDocument(
"tagged_actual_text.pdf"));
82 FPDF_PAGE page = LoadPage(0);
87 ASSERT_TRUE(struct_tree);
88 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
92 FPDF_STRUCTELEMENT element =
93 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
98 FPDF_STRUCTELEMENT child_element =
100 ASSERT_TRUE(child_element);
104 FPDF_STRUCTELEMENT gchild_element =
106 ASSERT_TRUE(gchild_element);
110 unsigned short buffer[12] = {};
114 for (
unsigned short b : buffer) {
126 ASSERT_TRUE(OpenDocument(
"tagged_table.pdf"));
127 FPDF_PAGE page = LoadPage(0);
132 ASSERT_TRUE(struct_tree);
133 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
135 FPDF_STRUCTELEMENT document =
136 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
137 ASSERT_TRUE(document);
139 constexpr int kBufLen = 100;
140 uint16_t buffer[kBufLen] = {0};
161 ASSERT_TRUE(header_cell);
189 ASSERT_TRUE(OpenDocument(
"tagged_table_bad_elem.pdf"));
190 FPDF_PAGE page = LoadPage(0);
195 ASSERT_TRUE(struct_tree);
196 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
198 FPDF_STRUCTELEMENT document =
199 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
200 ASSERT_TRUE(document);
202 constexpr int kBufLen = 100;
203 uint16_t buffer[kBufLen] = {0};
229 ASSERT_TRUE(OpenDocument(
"tagged_table.pdf"));
230 FPDF_PAGE page = LoadPage(0);
235 ASSERT_TRUE(struct_tree);
236 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
238 FPDF_STRUCTELEMENT document =
239 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
240 ASSERT_TRUE(document);
242 constexpr int kBufLen = 100;
243 uint16_t buffer[kBufLen] = {0};
274 ASSERT_TRUE(OpenDocument(
"tagged_table.pdf"));
275 FPDF_PAGE page = LoadPage(0);
280 ASSERT_TRUE(struct_tree);
281 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
283 FPDF_STRUCTELEMENT document =
284 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
285 ASSERT_TRUE(document);
287 constexpr int kBufLen = 100;
288 uint16_t buffer[kBufLen] = {0};
324 ASSERT_TRUE(OpenDocument(
"marked_content_id.pdf"));
325 FPDF_PAGE page = LoadPage(0);
330 ASSERT_TRUE(struct_tree);
331 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
333 FPDF_STRUCTELEMENT element =
334 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
342 ASSERT_TRUE(OpenDocument(
"tagged_marked_content.pdf"));
343 FPDF_PAGE page = LoadPage(0);
348 ASSERT_TRUE(struct_tree);
349 ASSERT_EQ(4, FPDF_StructTree_CountChildren(struct_tree.get()));
352 FPDF_STRUCTELEMENT child1 =
353 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
359 FPDF_STRUCTELEMENT child2 =
360 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 1);
364 FPDF_STRUCTELEMENT child3 =
365 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 2);
369 FPDF_STRUCTELEMENT child4 =
370 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 3);
396 ASSERT_TRUE(OpenDocument(
"tagged_mcr_multipage.pdf"));
399 for (
int page_i : {0, 1}) {
400 FPDF_PAGE page = LoadPage(page_i);
402 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
403 ASSERT_TRUE(struct_tree);
404 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
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));
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);
419 EXPECT_EQ(2, FPDF_StructElement_GetMarkedContentIdCount(struct_doc));
424 EXPECT_EQ(0, FPDF_StructElement_GetMarkedContentIdAtIndex(struct_doc, 0));
425 EXPECT_EQ(0, FPDF_StructElement_GetMarkedContentIdAtIndex(struct_doc, 1));
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));
434 EXPECT_EQ(-1, FPDF_StructElement_GetChildMarkedContentID(struct_doc, -1));
435 EXPECT_EQ(-1, FPDF_StructElement_GetChildMarkedContentID(struct_doc, 2));
437 EXPECT_EQ(-1, FPDF_StructElement_GetChildMarkedContentID(
nullptr, 0));
443 ASSERT_TRUE(OpenDocument(
"tagged_alt_text.pdf"));
444 FPDF_PAGE page = LoadPage(0);
449 ASSERT_TRUE(struct_tree);
450 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
452 FPDF_STRUCTELEMENT element =
453 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
454 ASSERT_TRUE(element);
457 unsigned short buffer[12] = {};
464 fxcrt::Fill(buffer, 0xbdfcu);
466 for (
const auto b : buffer) {
467 EXPECT_EQ(0xbdfcu, b);
477 ASSERT_TRUE(OpenDocument(
"tagged_table_bad_elem.pdf"));
478 FPDF_PAGE page = LoadPage(0);
483 ASSERT_TRUE(struct_tree);
484 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
486 FPDF_STRUCTELEMENT child =
487 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
491 unsigned short buffer[28] = {};
500 for (
unsigned short b : buffer) {
510 fxcrt::Fill(buffer, 0xbdfcu);
515 for (
const auto b : buffer) {
516 EXPECT_EQ(0xbdfcu, b);
530 ASSERT_TRUE(OpenDocument(
"tagged_alt_text.pdf"));
531 FPDF_PAGE page = LoadPage(0);
536 ASSERT_TRUE(struct_tree);
537 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
539 FPDF_STRUCTELEMENT parent =
540 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
562 ASSERT_TRUE(OpenDocument(
"tagged_alt_text.pdf"));
563 FPDF_PAGE page = LoadPage(0);
568 ASSERT_TRUE(struct_tree);
569 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
571 FPDF_STRUCTELEMENT element =
572 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
573 ASSERT_TRUE(element);
576 unsigned short buffer[13] = {};
583 fxcrt::Fill(buffer, 0xbdfcu);
585 for (
const auto b : buffer) {
586 EXPECT_EQ(0xbdfcu, b);
594 FPDF_STRUCTELEMENT child_element =
596 ASSERT_TRUE(element);
607 ASSERT_TRUE(OpenDocument(
"tagged_table.pdf"));
608 FPDF_PAGE page = LoadPage(0);
613 ASSERT_TRUE(struct_tree);
614 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
616 FPDF_STRUCTELEMENT document =
617 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
618 ASSERT_TRUE(document);
642 FPDF_STRUCTELEMENT_ATTR attr =
649 unsigned long buffer_len_needed = ULONG_MAX;
652 &buffer_len_needed
));
653 EXPECT_EQ(2U, buffer_len_needed);
655 unsigned long out_len = ULONG_MAX;
660 EXPECT_EQ(2U, out_len);
661 for (
unsigned short b : buffer) {
665 sizeof(buffer)
, &out_len
));
666 EXPECT_EQ(2U, out_len);
667 EXPECT_STREQ(
"O", buffer);
674 FPDF_STRUCTELEMENT_ATTR_VALUE attr_value =
676 ASSERT_TRUE(attr_value);
680 unsigned short str_val[12] = {};
682 attr_value
, str_val
, sizeof(str_val)
, &out_len
));
683 EXPECT_EQ(12U, out_len);
686 fxcrt::Fill(buffer, 0u);
688 sizeof(buffer)
, &out_len
));
689 EXPECT_EQ(8U, out_len);
690 EXPECT_STREQ(
"ColSpan", buffer);
692 ASSERT_TRUE(attr_value);
697 EXPECT_FLOAT_EQ(2.0f, num_val);
714 FPDF_STRUCTELEMENT_ATTR attr =
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);
727 FPDF_STRUCTELEMENT_ATTR_VALUE attr_value =
729 ASSERT_TRUE(attr_value);
733 unsigned short str_val[12] = {};
735 attr_value
, str_val
, sizeof(str_val)
, &out_len
));
736 EXPECT_EQ(8U, out_len);
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]);
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);
757 FPDF_STRUCTELEMENT_ATTR_VALUE attr_value =
759 ASSERT_TRUE(attr_value);
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);
777 FPDF_STRUCTELEMENT_ATTR_VALUE attr_value =
779 ASSERT_TRUE(attr_value);
784 EXPECT_FLOAT_EQ(3, val);
794 ASSERT_TRUE(OpenDocument(
"tagged_actual_text.pdf"));
795 FPDF_PAGE page = LoadPage(0);
800 ASSERT_TRUE(struct_tree);
801 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
803 FPDF_STRUCTELEMENT element =
804 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
805 ASSERT_TRUE(element);
808 FPDF_STRUCTELEMENT child_element =
810 ASSERT_TRUE(child_element);
813 FPDF_STRUCTELEMENT gchild_element =
815 ASSERT_TRUE(gchild_element);
817 int gchild_attr_count =
819 ASSERT_EQ(1, gchild_attr_count);
821 FPDF_STRUCTELEMENT_ATTR attr =
826 ASSERT_EQ(5, attr_count);
829 unsigned long required_len;
832 EXPECT_EQ(7u, required_len);
833 EXPECT_STREQ(
"Height", name);
841 FPDF_STRUCTELEMENT_ATTR_VALUE attr_value =
843 ASSERT_TRUE(attr_value);
854 EXPECT_EQ(5u, required_len);
855 EXPECT_STREQ(
"BBox", name);
857 FPDF_STRUCTELEMENT_ATTR_VALUE attr_value =
859 ASSERT_TRUE(attr_value);
862 FPDF_STRUCTELEMENT_ATTR_VALUE nested_attr_value0 =
864 ASSERT_TRUE(nested_attr_value0);
867 FPDF_STRUCTELEMENT_ATTR_VALUE nested_attr_value3 =
869 ASSERT_TRUE(nested_attr_value3);
878 ASSERT_TRUE(OpenDocument(
"tagged_nested.pdf"));
879 FPDF_PAGE page = LoadPage(0);
885 ASSERT_TRUE(struct_tree);
891 ASSERT_TRUE(OpenDocument(
"tagged_mcr_objr.pdf"));
892 FPDF_PAGE page = LoadPage(0);
897 ASSERT_TRUE(struct_tree);
898 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
900 FPDF_STRUCTELEMENT object8 =
901 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
902 ASSERT_TRUE(object8);
903 unsigned short buffer[12];
910 FPDF_STRUCTELEMENT object10 =
912 ASSERT_TRUE(object10);
919 FPDF_STRUCTELEMENT object12 =
921 ASSERT_TRUE(object12);
927 FPDF_STRUCTELEMENT object13 =
929 ASSERT_TRUE(object13);
941 FPDF_STRUCTELEMENT object11 =
943 ASSERT_TRUE(object11);
949 FPDF_STRUCTELEMENT object14 =
951 ASSERT_TRUE(object14);
960 FPDF_STRUCTELEMENT object15 =
962 ASSERT_TRUE(object15);
977 ASSERT_TRUE(OpenDocument(
"bug_1768.pdf"));
978 FPDF_PAGE page = LoadPage(0);
983 ASSERT_TRUE(struct_tree);
984 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
989 EXPECT_FALSE(FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0));
996 ASSERT_TRUE(OpenDocument(
"bug_1296920.pdf"));
997 FPDF_PAGE page = LoadPage(0);
1002 ASSERT_TRUE(struct_tree);
1003 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
1012 ASSERT_TRUE(OpenDocument(
"tagged_table_bad_parent.pdf"));
1013 FPDF_PAGE page = LoadPage(0);
1019 ASSERT_TRUE(struct_tree);
1020 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
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
#define FPDF_OBJECT_BOOLEAN
#define FPDF_OBJECT_STRING
#define FPDF_OBJECT_ARRAY
std::string GetPlatformString(FPDF_WIDESTRING wstr)
std::wstring GetPlatformWString(FPDF_WIDESTRING wstr)