1 // Copyright 2016 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
5 #include "core/fxcrt/fx_string.h"
6 #include "public/fpdf_structtree.h"
7 #include "testing/embedder_test.h"
8 #include "third_party/base/optional.h"
9
10 class FPDFStructTreeEmbedderTest : public EmbedderTest {};
11
TEST_F(FPDFStructTreeEmbedderTest,GetAltText)12 TEST_F(FPDFStructTreeEmbedderTest, GetAltText) {
13 ASSERT_TRUE(OpenDocument("tagged_alt_text.pdf"));
14 FPDF_PAGE page = LoadPage(0);
15 ASSERT_TRUE(page);
16
17 {
18 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
19 ASSERT_TRUE(struct_tree);
20 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
21
22 FPDF_STRUCTELEMENT element =
23 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), -1);
24 EXPECT_EQ(nullptr, element);
25 element = FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 1);
26 EXPECT_EQ(nullptr, element);
27 element = FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
28 ASSERT_NE(nullptr, element);
29 EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(element));
30 EXPECT_EQ(0U, FPDF_StructElement_GetAltText(element, nullptr, 0));
31
32 ASSERT_EQ(1, FPDF_StructElement_CountChildren(element));
33 FPDF_STRUCTELEMENT child_element =
34 FPDF_StructElement_GetChildAtIndex(element, -1);
35 EXPECT_EQ(nullptr, child_element);
36 child_element = FPDF_StructElement_GetChildAtIndex(element, 1);
37 EXPECT_EQ(nullptr, child_element);
38 child_element = FPDF_StructElement_GetChildAtIndex(element, 0);
39 ASSERT_NE(nullptr, child_element);
40 EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(child_element));
41 EXPECT_EQ(0U, FPDF_StructElement_GetAltText(child_element, nullptr, 0));
42
43 ASSERT_EQ(1, FPDF_StructElement_CountChildren(child_element));
44 FPDF_STRUCTELEMENT gchild_element =
45 FPDF_StructElement_GetChildAtIndex(child_element, -1);
46 EXPECT_EQ(nullptr, gchild_element);
47 gchild_element = FPDF_StructElement_GetChildAtIndex(child_element, 1);
48 EXPECT_EQ(nullptr, gchild_element);
49 gchild_element = FPDF_StructElement_GetChildAtIndex(child_element, 0);
50 ASSERT_NE(nullptr, gchild_element);
51 EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(gchild_element));
52 ASSERT_EQ(24U, FPDF_StructElement_GetAltText(gchild_element, nullptr, 0));
53
54 unsigned short buffer[12];
55 memset(buffer, 0, sizeof(buffer));
56 // Deliberately pass in a small buffer size to make sure |buffer| remains
57 // untouched.
58 ASSERT_EQ(24U, FPDF_StructElement_GetAltText(gchild_element, buffer, 1));
59 for (size_t i = 0; i < FX_ArraySize(buffer); ++i)
60 EXPECT_EQ(0U, buffer[i]);
61
62 EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(gchild_element));
63 ASSERT_EQ(24U, FPDF_StructElement_GetAltText(gchild_element, buffer,
64 sizeof(buffer)));
65 const wchar_t kExpected[] = L"Black Image";
66 EXPECT_EQ(WideString(kExpected),
67 WideString::FromUTF16LE(buffer, FXSYS_len(kExpected)));
68
69 ASSERT_EQ(1, FPDF_StructElement_CountChildren(gchild_element));
70 FPDF_STRUCTELEMENT ggchild_element =
71 FPDF_StructElement_GetChildAtIndex(gchild_element, 0);
72 EXPECT_EQ(nullptr, ggchild_element);
73 }
74
75 UnloadPage(page);
76 }
77
TEST_F(FPDFStructTreeEmbedderTest,GetMarkedContentID)78 TEST_F(FPDFStructTreeEmbedderTest, GetMarkedContentID) {
79 ASSERT_TRUE(OpenDocument("marked_content_id.pdf"));
80 FPDF_PAGE page = LoadPage(0);
81 ASSERT_TRUE(page);
82
83 {
84 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
85 ASSERT_TRUE(struct_tree);
86 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
87
88 FPDF_STRUCTELEMENT element =
89 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
90 EXPECT_EQ(0, FPDF_StructElement_GetMarkedContentID(element));
91 }
92
93 UnloadPage(page);
94 }
95
TEST_F(FPDFStructTreeEmbedderTest,GetType)96 TEST_F(FPDFStructTreeEmbedderTest, GetType) {
97 ASSERT_TRUE(OpenDocument("tagged_alt_text.pdf"));
98 FPDF_PAGE page = LoadPage(0);
99 ASSERT_TRUE(page);
100
101 {
102 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
103 ASSERT_TRUE(struct_tree);
104 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
105
106 FPDF_STRUCTELEMENT element =
107 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
108 ASSERT_NE(nullptr, element);
109
110 // test nullptr inputs
111 unsigned short buffer[12];
112 ASSERT_EQ(0U, FPDF_StructElement_GetType(nullptr, buffer, sizeof(buffer)));
113 ASSERT_EQ(0U, FPDF_StructElement_GetType(nullptr, nullptr, 0));
114 ASSERT_EQ(18U, FPDF_StructElement_GetType(element, nullptr, 0));
115
116 memset(buffer, 0, sizeof(buffer));
117 // Deliberately pass in a small buffer size to make sure |buffer| remains
118 // untouched.
119 ASSERT_EQ(18U, FPDF_StructElement_GetType(element, buffer, 1));
120 for (size_t i = 0; i < FX_ArraySize(buffer); ++i)
121 EXPECT_EQ(0U, buffer[i]);
122
123 ASSERT_EQ(18U, FPDF_StructElement_GetType(element, buffer, sizeof(buffer)));
124 const wchar_t kExpected[] = L"Document";
125 EXPECT_EQ(WideString(kExpected),
126 WideString::FromUTF16LE(buffer, FXSYS_len(kExpected)));
127 }
128
129 UnloadPage(page);
130 }
131
TEST_F(FPDFStructTreeEmbedderTest,GetTitle)132 TEST_F(FPDFStructTreeEmbedderTest, GetTitle) {
133 ASSERT_TRUE(OpenDocument("tagged_alt_text.pdf"));
134 FPDF_PAGE page = LoadPage(0);
135 ASSERT_TRUE(page);
136
137 {
138 ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page));
139 ASSERT_TRUE(struct_tree);
140 ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get()));
141
142 FPDF_STRUCTELEMENT element =
143 FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0);
144 ASSERT_NE(nullptr, element);
145
146 // test nullptr inputs
147 unsigned short buffer[13];
148 ASSERT_EQ(0U, FPDF_StructElement_GetTitle(nullptr, buffer, sizeof(buffer)));
149 ASSERT_EQ(0U, FPDF_StructElement_GetTitle(nullptr, nullptr, 0));
150 ASSERT_EQ(20U, FPDF_StructElement_GetTitle(element, nullptr, 0));
151
152 memset(buffer, 0, sizeof(buffer));
153 // Deliberately pass in a small buffer size to make sure |buffer| remains
154 // untouched.
155 ASSERT_EQ(20U, FPDF_StructElement_GetTitle(element, buffer, 1));
156 for (size_t i = 0; i < FX_ArraySize(buffer); ++i)
157 EXPECT_EQ(0U, buffer[i]);
158
159 ASSERT_EQ(20U,
160 FPDF_StructElement_GetTitle(element, buffer, sizeof(buffer)));
161
162 const wchar_t kExpected[] = L"TitleText";
163 EXPECT_EQ(WideString(kExpected),
164 WideString::FromUTF16LE(buffer, FXSYS_len(kExpected)));
165
166 ASSERT_EQ(1, FPDF_StructElement_CountChildren(element));
167 FPDF_STRUCTELEMENT child_element =
168 FPDF_StructElement_GetChildAtIndex(element, 0);
169 ASSERT_NE(nullptr, element);
170
171 ASSERT_EQ(26U, FPDF_StructElement_GetTitle(child_element, buffer,
172 sizeof(buffer)));
173 const wchar_t kChildExpected[] = L"symbol: 100k";
174 EXPECT_EQ(WideString(kChildExpected),
175 WideString::FromUTF16LE(buffer, FXSYS_len(kChildExpected)));
176 }
177
178 UnloadPage(page);
179 }
180