blob: e662bbe6e5031369af683a59885b098d45115761 [file] [log] [blame]
Tom Sepez26b8a5b2015-01-27 12:42:36 -08001// Copyright 2015 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
Dan Sinclair85c8e7f2016-11-21 13:50:32 -05005#include <memory>
6
Dan Sinclairbcd1e702017-08-31 13:19:18 -04007#include "core/fxcrt/fx_memory.h"
Lei Zhangb4e7f302015-11-06 15:52:32 -08008#include "public/fpdf_text.h"
9#include "public/fpdfview.h"
Wei Li091f7a02015-11-09 12:09:55 -080010#include "testing/embedder_test.h"
Tom Sepez26b8a5b2015-01-27 12:42:36 -080011#include "testing/gtest/include/gtest/gtest.h"
Dan Sinclair61046b92016-02-18 14:48:48 -050012#include "testing/test_support.h"
Tom Sepez26b8a5b2015-01-27 12:42:36 -080013
Tom Sepez526f6d52015-01-28 15:49:13 -080014namespace {
15
Lei Zhang0f2ea022016-01-11 12:01:23 -080016bool check_unsigned_shorts(const char* expected,
17 const unsigned short* actual,
18 size_t length) {
Tom Sepez526f6d52015-01-28 15:49:13 -080019 if (length > strlen(expected) + 1) {
20 return false;
21 }
22 for (size_t i = 0; i < length; ++i) {
23 if (actual[i] != static_cast<unsigned short>(expected[i])) {
24 return false;
25 }
26 }
27 return true;
28}
29
30} // namespace
31
Nico Weber9d8ec5a2015-08-04 13:00:21 -070032class FPDFTextEmbeddertest : public EmbedderTest {};
Tom Sepez26b8a5b2015-01-27 12:42:36 -080033
Tom Sepez526f6d52015-01-28 15:49:13 -080034TEST_F(FPDFTextEmbeddertest, Text) {
Wei Li091f7a02015-11-09 12:09:55 -080035 EXPECT_TRUE(OpenDocument("hello_world.pdf"));
Tom Sepezda8189e2015-01-30 14:41:50 -080036 FPDF_PAGE page = LoadPage(0);
thestig4997b222016-06-07 10:46:22 -070037 EXPECT_TRUE(page);
Tom Sepez526f6d52015-01-28 15:49:13 -080038
39 FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
thestig4997b222016-06-07 10:46:22 -070040 EXPECT_TRUE(textpage);
Tom Sepez526f6d52015-01-28 15:49:13 -080041
Lei Zhangd27acae2015-05-15 15:36:02 -070042 static const char expected[] = "Hello, world!\r\nGoodbye, world!";
Tom Sepez526f6d52015-01-28 15:49:13 -080043 unsigned short fixed_buffer[128];
44 memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
45
46 // Check includes the terminating NUL that is provided.
Lei Zhanga0f67242015-08-17 15:39:30 -070047 int num_chars = FPDFText_GetText(textpage, 0, 128, fixed_buffer);
48 ASSERT_GE(num_chars, 0);
Oliver Chang35e68a52015-12-09 12:44:33 -080049 EXPECT_EQ(sizeof(expected), static_cast<size_t>(num_chars));
50 EXPECT_TRUE(check_unsigned_shorts(expected, fixed_buffer, sizeof(expected)));
Tom Sepez526f6d52015-01-28 15:49:13 -080051
52 // Count does not include the terminating NUL in the string literal.
Wei Li05d53f02016-03-29 16:42:53 -070053 EXPECT_EQ(sizeof(expected) - 1,
54 static_cast<size_t>(FPDFText_CountChars(textpage)));
Tom Sepez526f6d52015-01-28 15:49:13 -080055 for (size_t i = 0; i < sizeof(expected) - 1; ++i) {
Lei Zhanga0f67242015-08-17 15:39:30 -070056 EXPECT_EQ(static_cast<unsigned int>(expected[i]),
57 FPDFText_GetUnicode(textpage, i))
58 << " at " << i;
Tom Sepez526f6d52015-01-28 15:49:13 -080059 }
60
61 EXPECT_EQ(12.0, FPDFText_GetFontSize(textpage, 0));
62 EXPECT_EQ(16.0, FPDFText_GetFontSize(textpage, 15));
63
64 double left = 0.0;
65 double right = 0.0;
66 double bottom = 0.0;
67 double top = 0.0;
68 FPDFText_GetCharBox(textpage, 4, &left, &right, &bottom, &top);
69 EXPECT_NEAR(41.071, left, 0.001);
70 EXPECT_NEAR(46.243, right, 0.001);
71 EXPECT_NEAR(49.844, bottom, 0.001);
72 EXPECT_NEAR(55.520, top, 0.001);
73
Andrew Weintraubd3002342017-08-11 11:36:51 -040074 double x = 0.0;
75 double y = 0.0;
76 EXPECT_TRUE(FPDFText_GetCharOrigin(textpage, 4, &x, &y));
77 EXPECT_NEAR(40.664, x, 0.001);
78 EXPECT_NEAR(50.000, y, 0.001);
79
Nico Weber9d8ec5a2015-08-04 13:00:21 -070080 EXPECT_EQ(4, FPDFText_GetCharIndexAtPos(textpage, 42.0, 50.0, 1.0, 1.0));
81 EXPECT_EQ(-1, FPDFText_GetCharIndexAtPos(textpage, 0.0, 0.0, 1.0, 1.0));
82 EXPECT_EQ(-1, FPDFText_GetCharIndexAtPos(textpage, 199.0, 199.0, 1.0, 1.0));
Tom Sepez526f6d52015-01-28 15:49:13 -080083
84 // Test out of range indicies.
Nico Weber9d8ec5a2015-08-04 13:00:21 -070085 EXPECT_EQ(-1,
86 FPDFText_GetCharIndexAtPos(textpage, 42.0, 10000000.0, 1.0, 1.0));
87 EXPECT_EQ(-1, FPDFText_GetCharIndexAtPos(textpage, -1.0, 50.0, 1.0, 1.0));
Tom Sepez526f6d52015-01-28 15:49:13 -080088
89 // Count does not include the terminating NUL in the string literal.
90 EXPECT_EQ(2, FPDFText_CountRects(textpage, 0, sizeof(expected) - 1));
91
92 left = 0.0;
93 right = 0.0;
94 bottom = 0.0;
95 top = 0.0;
96 FPDFText_GetRect(textpage, 1, &left, &top, &right, &bottom);
97 EXPECT_NEAR(20.847, left, 0.001);
98 EXPECT_NEAR(135.167, right, 0.001);
99 EXPECT_NEAR(96.655, bottom, 0.001);
100 EXPECT_NEAR(116.000, top, 0.001);
101
102 // Test out of range indicies set outputs to (0.0, 0.0, 0.0, 0.0).
103 left = -1.0;
104 right = -1.0;
105 bottom = -1.0;
106 top = -1.0;
107 FPDFText_GetRect(textpage, -1, &left, &top, &right, &bottom);
108 EXPECT_EQ(0.0, left);
109 EXPECT_EQ(0.0, right);
110 EXPECT_EQ(0.0, bottom);
111 EXPECT_EQ(0.0, top);
112
113 left = -2.0;
114 right = -2.0;
115 bottom = -2.0;
116 top = -2.0;
117 FPDFText_GetRect(textpage, 2, &left, &top, &right, &bottom);
118 EXPECT_EQ(0.0, left);
119 EXPECT_EQ(0.0, right);
120 EXPECT_EQ(0.0, bottom);
121 EXPECT_EQ(0.0, top);
122
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123 EXPECT_EQ(9, FPDFText_GetBoundedText(textpage, 41.0, 56.0, 82.0, 48.0, 0, 0));
Tom Sepez526f6d52015-01-28 15:49:13 -0800124
125 // Extract starting at character 4 as above.
126 memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127 EXPECT_EQ(1, FPDFText_GetBoundedText(textpage, 41.0, 56.0, 82.0, 48.0,
128 fixed_buffer, 1));
Tom Sepez526f6d52015-01-28 15:49:13 -0800129 EXPECT_TRUE(check_unsigned_shorts(expected + 4, fixed_buffer, 1));
130 EXPECT_EQ(0xbdbd, fixed_buffer[1]);
131
132 memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700133 EXPECT_EQ(9, FPDFText_GetBoundedText(textpage, 41.0, 56.0, 82.0, 48.0,
134 fixed_buffer, 9));
Tom Sepez526f6d52015-01-28 15:49:13 -0800135 EXPECT_TRUE(check_unsigned_shorts(expected + 4, fixed_buffer, 9));
136 EXPECT_EQ(0xbdbd, fixed_buffer[9]);
137
138 memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
Oliver Chang35e68a52015-12-09 12:44:33 -0800139 EXPECT_EQ(10, FPDFText_GetBoundedText(textpage, 41.0, 56.0, 82.0, 48.0,
140 fixed_buffer, 128));
Tom Sepez526f6d52015-01-28 15:49:13 -0800141 EXPECT_TRUE(check_unsigned_shorts(expected + 4, fixed_buffer, 9));
Oliver Chang35e68a52015-12-09 12:44:33 -0800142 EXPECT_EQ(0u, fixed_buffer[9]);
143 EXPECT_EQ(0xbdbd, fixed_buffer[10]);
Tom Sepez526f6d52015-01-28 15:49:13 -0800144
145 FPDFText_ClosePage(textpage);
Lei Zhangd27acae2015-05-15 15:36:02 -0700146 UnloadPage(page);
Tom Sepez526f6d52015-01-28 15:49:13 -0800147}
148
149TEST_F(FPDFTextEmbeddertest, TextSearch) {
Wei Li091f7a02015-11-09 12:09:55 -0800150 EXPECT_TRUE(OpenDocument("hello_world.pdf"));
Tom Sepezda8189e2015-01-30 14:41:50 -0800151 FPDF_PAGE page = LoadPage(0);
thestig4997b222016-06-07 10:46:22 -0700152 EXPECT_TRUE(page);
Tom Sepez526f6d52015-01-28 15:49:13 -0800153
154 FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
thestig4997b222016-06-07 10:46:22 -0700155 EXPECT_TRUE(textpage);
Tom Sepez526f6d52015-01-28 15:49:13 -0800156
Tom Sepez0aa35312016-01-06 10:16:32 -0800157 std::unique_ptr<unsigned short, pdfium::FreeDeleter> nope =
158 GetFPDFWideString(L"nope");
159 std::unique_ptr<unsigned short, pdfium::FreeDeleter> world =
160 GetFPDFWideString(L"world");
161 std::unique_ptr<unsigned short, pdfium::FreeDeleter> world_caps =
162 GetFPDFWideString(L"WORLD");
163 std::unique_ptr<unsigned short, pdfium::FreeDeleter> world_substr =
164 GetFPDFWideString(L"orld");
Tom Sepez526f6d52015-01-28 15:49:13 -0800165
166 // No occurences of "nope" in test page.
Tom Sepez0aa35312016-01-06 10:16:32 -0800167 FPDF_SCHHANDLE search = FPDFText_FindStart(textpage, nope.get(), 0, 0);
thestig4997b222016-06-07 10:46:22 -0700168 EXPECT_TRUE(search);
Tom Sepez526f6d52015-01-28 15:49:13 -0800169 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
170 EXPECT_EQ(0, FPDFText_GetSchCount(search));
171
172 // Advancing finds nothing.
173 EXPECT_FALSE(FPDFText_FindNext(search));
174 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
175 EXPECT_EQ(0, FPDFText_GetSchCount(search));
176
177 // Retreating finds nothing.
178 EXPECT_FALSE(FPDFText_FindPrev(search));
179 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
180 EXPECT_EQ(0, FPDFText_GetSchCount(search));
181 FPDFText_FindClose(search);
182
183 // Two occurences of "world" in test page.
Tom Sepez0aa35312016-01-06 10:16:32 -0800184 search = FPDFText_FindStart(textpage, world.get(), 0, 2);
thestig4997b222016-06-07 10:46:22 -0700185 EXPECT_TRUE(search);
Tom Sepez526f6d52015-01-28 15:49:13 -0800186
187 // Remains not found until advanced.
188 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
189 EXPECT_EQ(0, FPDFText_GetSchCount(search));
190
191 // First occurence of "world" in this test page.
192 EXPECT_TRUE(FPDFText_FindNext(search));
193 EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
194 EXPECT_EQ(5, FPDFText_GetSchCount(search));
195
196 // Last occurence of "world" in this test page.
197 EXPECT_TRUE(FPDFText_FindNext(search));
198 EXPECT_EQ(24, FPDFText_GetSchResultIndex(search));
199 EXPECT_EQ(5, FPDFText_GetSchCount(search));
200
201 // Found position unchanged when fails to advance.
202 EXPECT_FALSE(FPDFText_FindNext(search));
203 EXPECT_EQ(24, FPDFText_GetSchResultIndex(search));
204 EXPECT_EQ(5, FPDFText_GetSchCount(search));
205
206 // Back to first occurence.
207 EXPECT_TRUE(FPDFText_FindPrev(search));
208 EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
209 EXPECT_EQ(5, FPDFText_GetSchCount(search));
210
211 // Found position unchanged when fails to retreat.
212 EXPECT_FALSE(FPDFText_FindPrev(search));
213 EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
214 EXPECT_EQ(5, FPDFText_GetSchCount(search));
215 FPDFText_FindClose(search);
216
217 // Exact search unaffected by case sensitiity and whole word flags.
Tom Sepez0aa35312016-01-06 10:16:32 -0800218 search = FPDFText_FindStart(textpage, world.get(),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700219 FPDF_MATCHCASE | FPDF_MATCHWHOLEWORD, 0);
thestig4997b222016-06-07 10:46:22 -0700220 EXPECT_TRUE(search);
Tom Sepez526f6d52015-01-28 15:49:13 -0800221 EXPECT_TRUE(FPDFText_FindNext(search));
222 EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
223 EXPECT_EQ(5, FPDFText_GetSchCount(search));
224 FPDFText_FindClose(search);
225
226 // Default is case-insensitive, so matching agaist caps works.
Tom Sepez0aa35312016-01-06 10:16:32 -0800227 search = FPDFText_FindStart(textpage, world_caps.get(), 0, 0);
thestig4997b222016-06-07 10:46:22 -0700228 EXPECT_TRUE(search);
Tom Sepez526f6d52015-01-28 15:49:13 -0800229 EXPECT_TRUE(FPDFText_FindNext(search));
230 EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
231 EXPECT_EQ(5, FPDFText_GetSchCount(search));
232 FPDFText_FindClose(search);
233
234 // But can be made case sensitive, in which case this fails.
Tom Sepez0aa35312016-01-06 10:16:32 -0800235 search = FPDFText_FindStart(textpage, world_caps.get(), FPDF_MATCHCASE, 0);
Tom Sepez526f6d52015-01-28 15:49:13 -0800236 EXPECT_FALSE(FPDFText_FindNext(search));
237 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
238 EXPECT_EQ(0, FPDFText_GetSchCount(search));
239 FPDFText_FindClose(search);
240
241 // Default is match anywhere within word, so matching substirng works.
Tom Sepez0aa35312016-01-06 10:16:32 -0800242 search = FPDFText_FindStart(textpage, world_substr.get(), 0, 0);
Tom Sepez526f6d52015-01-28 15:49:13 -0800243 EXPECT_TRUE(FPDFText_FindNext(search));
244 EXPECT_EQ(8, FPDFText_GetSchResultIndex(search));
245 EXPECT_EQ(4, FPDFText_GetSchCount(search));
246 FPDFText_FindClose(search);
247
248 // But can be made to mach word boundaries, in which case this fails.
Tom Sepez0aa35312016-01-06 10:16:32 -0800249 search =
250 FPDFText_FindStart(textpage, world_substr.get(), FPDF_MATCHWHOLEWORD, 0);
Tom Sepez526f6d52015-01-28 15:49:13 -0800251 EXPECT_FALSE(FPDFText_FindNext(search));
252 // TODO(tsepez): investigate strange index/count values in this state.
253 FPDFText_FindClose(search);
254
255 FPDFText_ClosePage(textpage);
Lei Zhangd27acae2015-05-15 15:36:02 -0700256 UnloadPage(page);
Tom Sepez526f6d52015-01-28 15:49:13 -0800257}
258
Tom Sepez26b8a5b2015-01-27 12:42:36 -0800259// Test that the page has characters despite a bad stream length.
260TEST_F(FPDFTextEmbeddertest, StreamLengthPastEndOfFile) {
Wei Li091f7a02015-11-09 12:09:55 -0800261 EXPECT_TRUE(OpenDocument("bug_57.pdf"));
Tom Sepezda8189e2015-01-30 14:41:50 -0800262 FPDF_PAGE page = LoadPage(0);
thestig4997b222016-06-07 10:46:22 -0700263 EXPECT_TRUE(page);
Tom Sepez526f6d52015-01-28 15:49:13 -0800264
Tom Sepez26b8a5b2015-01-27 12:42:36 -0800265 FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
thestig4997b222016-06-07 10:46:22 -0700266 EXPECT_TRUE(textpage);
Tom Sepez26b8a5b2015-01-27 12:42:36 -0800267 EXPECT_EQ(13, FPDFText_CountChars(textpage));
Tom Sepez526f6d52015-01-28 15:49:13 -0800268
269 FPDFText_ClosePage(textpage);
Lei Zhangd27acae2015-05-15 15:36:02 -0700270 UnloadPage(page);
Tom Sepez526f6d52015-01-28 15:49:13 -0800271}
272
273TEST_F(FPDFTextEmbeddertest, WebLinks) {
Wei Li091f7a02015-11-09 12:09:55 -0800274 EXPECT_TRUE(OpenDocument("weblinks.pdf"));
Tom Sepezda8189e2015-01-30 14:41:50 -0800275 FPDF_PAGE page = LoadPage(0);
thestig4997b222016-06-07 10:46:22 -0700276 EXPECT_TRUE(page);
Tom Sepez526f6d52015-01-28 15:49:13 -0800277
278 FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
thestig4997b222016-06-07 10:46:22 -0700279 EXPECT_TRUE(textpage);
Tom Sepez526f6d52015-01-28 15:49:13 -0800280
281 FPDF_PAGELINK pagelink = FPDFLink_LoadWebLinks(textpage);
thestig4997b222016-06-07 10:46:22 -0700282 EXPECT_TRUE(pagelink);
Tom Sepez526f6d52015-01-28 15:49:13 -0800283
284 // Page contains two HTTP-style URLs.
285 EXPECT_EQ(2, FPDFLink_CountWebLinks(pagelink));
286
Oliver Chang35e68a52015-12-09 12:44:33 -0800287 // Only a terminating NUL required for bogus links.
288 EXPECT_EQ(1, FPDFLink_GetURL(pagelink, 2, nullptr, 0));
289 EXPECT_EQ(1, FPDFLink_GetURL(pagelink, 1400, nullptr, 0));
290 EXPECT_EQ(1, FPDFLink_GetURL(pagelink, -1, nullptr, 0));
Tom Sepez526f6d52015-01-28 15:49:13 -0800291
292 // Query the number of characters required for each link (incl NUL).
Oliver Chang35e68a52015-12-09 12:44:33 -0800293 EXPECT_EQ(25, FPDFLink_GetURL(pagelink, 0, nullptr, 0));
294 EXPECT_EQ(26, FPDFLink_GetURL(pagelink, 1, nullptr, 0));
Tom Sepez526f6d52015-01-28 15:49:13 -0800295
Lei Zhangd27acae2015-05-15 15:36:02 -0700296 static const char expected_url[] = "http://example.com?q=foo";
Wei Li05d53f02016-03-29 16:42:53 -0700297 static const size_t expected_len = sizeof(expected_url);
Tom Sepez526f6d52015-01-28 15:49:13 -0800298 unsigned short fixed_buffer[128];
299
300 // Retrieve a link with too small a buffer. Buffer will not be
301 // NUL-terminated, but must not be modified past indicated length,
302 // so pre-fill with a pattern to check write bounds.
303 memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
304 EXPECT_EQ(1, FPDFLink_GetURL(pagelink, 0, fixed_buffer, 1));
305 EXPECT_TRUE(check_unsigned_shorts(expected_url, fixed_buffer, 1));
306 EXPECT_EQ(0xbdbd, fixed_buffer[1]);
307
308 // Check buffer that doesn't have space for a terminating NUL.
309 memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
Wei Li05d53f02016-03-29 16:42:53 -0700310 EXPECT_EQ(static_cast<int>(expected_len - 1),
311 FPDFLink_GetURL(pagelink, 0, fixed_buffer, expected_len - 1));
312 EXPECT_TRUE(
313 check_unsigned_shorts(expected_url, fixed_buffer, expected_len - 1));
314 EXPECT_EQ(0xbdbd, fixed_buffer[expected_len - 1]);
Tom Sepez526f6d52015-01-28 15:49:13 -0800315
316 // Retreive link with exactly-sized buffer.
317 memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
Wei Li05d53f02016-03-29 16:42:53 -0700318 EXPECT_EQ(static_cast<int>(expected_len),
319 FPDFLink_GetURL(pagelink, 0, fixed_buffer, expected_len));
320 EXPECT_TRUE(check_unsigned_shorts(expected_url, fixed_buffer, expected_len));
321 EXPECT_EQ(0u, fixed_buffer[expected_len - 1]);
322 EXPECT_EQ(0xbdbd, fixed_buffer[expected_len]);
Tom Sepez526f6d52015-01-28 15:49:13 -0800323
324 // Retreive link with ample-sized-buffer.
325 memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
Wei Li05d53f02016-03-29 16:42:53 -0700326 EXPECT_EQ(static_cast<int>(expected_len),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700327 FPDFLink_GetURL(pagelink, 0, fixed_buffer, 128));
Wei Li05d53f02016-03-29 16:42:53 -0700328 EXPECT_TRUE(check_unsigned_shorts(expected_url, fixed_buffer, expected_len));
329 EXPECT_EQ(0u, fixed_buffer[expected_len - 1]);
330 EXPECT_EQ(0xbdbd, fixed_buffer[expected_len]);
Tom Sepez526f6d52015-01-28 15:49:13 -0800331
332 // Each link rendered in a single rect in this test page.
333 EXPECT_EQ(1, FPDFLink_CountRects(pagelink, 0));
334 EXPECT_EQ(1, FPDFLink_CountRects(pagelink, 1));
335
336 // Each link rendered in a single rect in this test page.
337 EXPECT_EQ(0, FPDFLink_CountRects(pagelink, -1));
338 EXPECT_EQ(0, FPDFLink_CountRects(pagelink, 2));
339 EXPECT_EQ(0, FPDFLink_CountRects(pagelink, 10000));
340
341 // Check boundary of valid link index with valid rect index.
342 double left = 0.0;
343 double right = 0.0;
344 double top = 0.0;
345 double bottom = 0.0;
346 FPDFLink_GetRect(pagelink, 0, 0, &left, &top, &right, &bottom);
347 EXPECT_NEAR(50.791, left, 0.001);
348 EXPECT_NEAR(187.963, right, 0.001);
349 EXPECT_NEAR(97.624, bottom, 0.001);
350 EXPECT_NEAR(108.736, top, 0.001);
351
352 // Check that valid link with invalid rect index leaves parameters unchanged.
353 left = -1.0;
354 right = -1.0;
355 top = -1.0;
356 bottom = -1.0;
357 FPDFLink_GetRect(pagelink, 0, 1, &left, &top, &right, &bottom);
358 EXPECT_EQ(-1.0, left);
359 EXPECT_EQ(-1.0, right);
360 EXPECT_EQ(-1.0, bottom);
361 EXPECT_EQ(-1.0, top);
362
363 // Check that invalid link index leaves parameters unchanged.
364 left = -2.0;
365 right = -2.0;
366 top = -2.0;
367 bottom = -2.0;
368 FPDFLink_GetRect(pagelink, -1, 0, &left, &top, &right, &bottom);
369 EXPECT_EQ(-2.0, left);
370 EXPECT_EQ(-2.0, right);
371 EXPECT_EQ(-2.0, bottom);
372 EXPECT_EQ(-2.0, top);
373
374 FPDFLink_CloseWebLinks(pagelink);
375 FPDFText_ClosePage(textpage);
Lei Zhangd27acae2015-05-15 15:36:02 -0700376 UnloadPage(page);
Tom Sepez26b8a5b2015-01-27 12:42:36 -0800377}
Lei Zhang0f2ea022016-01-11 12:01:23 -0800378
Wei Li76309072017-03-16 17:31:03 -0700379TEST_F(FPDFTextEmbeddertest, WebLinksAcrossLines) {
380 EXPECT_TRUE(OpenDocument("weblinks_across_lines.pdf"));
381 FPDF_PAGE page = LoadPage(0);
382 EXPECT_TRUE(page);
383
384 FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
385 EXPECT_TRUE(textpage);
386
387 FPDF_PAGELINK pagelink = FPDFLink_LoadWebLinks(textpage);
388 EXPECT_TRUE(pagelink);
389
390 static const char* const kExpectedUrls[] = {
Wei Li6c8ed642017-05-19 22:17:38 -0700391 "http://example.com", // from "http://www.example.com?\r\nfoo"
Wei Li76309072017-03-16 17:31:03 -0700392 "http://example.com/", // from "http://www.example.com/\r\nfoo"
393 "http://example.com/test-foo", // from "http://example.com/test-\r\nfoo"
394 "http://abc.com/test-foo", // from "http://abc.com/test-\r\n\r\nfoo"
395 // Next two links from "http://www.example.com/\r\nhttp://www.abc.com/"
396 "http://example.com/", "http://www.abc.com",
397 };
398 static const int kNumLinks = static_cast<int>(FX_ArraySize(kExpectedUrls));
399
400 EXPECT_EQ(kNumLinks, FPDFLink_CountWebLinks(pagelink));
401
402 unsigned short fixed_buffer[128];
403 for (int i = 0; i < kNumLinks; i++) {
404 const size_t expected_len = strlen(kExpectedUrls[i]) + 1;
405 memset(fixed_buffer, 0, FX_ArraySize(fixed_buffer));
406 EXPECT_EQ(static_cast<int>(expected_len),
407 FPDFLink_GetURL(pagelink, i, nullptr, 0));
408 EXPECT_EQ(
409 static_cast<int>(expected_len),
410 FPDFLink_GetURL(pagelink, i, fixed_buffer, FX_ArraySize(fixed_buffer)));
411 EXPECT_TRUE(
412 check_unsigned_shorts(kExpectedUrls[i], fixed_buffer, expected_len));
413 }
414
415 FPDFLink_CloseWebLinks(pagelink);
416 FPDFText_ClosePage(textpage);
417 UnloadPage(page);
418}
419
420TEST_F(FPDFTextEmbeddertest, WebLinksAcrossLinesBug) {
421 EXPECT_TRUE(OpenDocument("bug_650.pdf"));
422 FPDF_PAGE page = LoadPage(0);
423 EXPECT_TRUE(page);
424
425 FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
426 EXPECT_TRUE(textpage);
427
428 FPDF_PAGELINK pagelink = FPDFLink_LoadWebLinks(textpage);
429 EXPECT_TRUE(pagelink);
430
431 EXPECT_EQ(2, FPDFLink_CountWebLinks(pagelink));
432 unsigned short fixed_buffer[128] = {0};
433 static const char kExpectedUrl[] =
434 "http://tutorial45.com/learn-autocad-basics-day-166/";
435 static const int kUrlSize = static_cast<int>(sizeof(kExpectedUrl));
436
437 EXPECT_EQ(kUrlSize, FPDFLink_GetURL(pagelink, 1, nullptr, 0));
438 EXPECT_EQ(kUrlSize, FPDFLink_GetURL(pagelink, 1, fixed_buffer,
439 FX_ArraySize(fixed_buffer)));
440 EXPECT_TRUE(check_unsigned_shorts(kExpectedUrl, fixed_buffer, kUrlSize));
441
442 FPDFLink_CloseWebLinks(pagelink);
443 FPDFText_ClosePage(textpage);
444 UnloadPage(page);
445}
446
Lei Zhang0f2ea022016-01-11 12:01:23 -0800447TEST_F(FPDFTextEmbeddertest, GetFontSize) {
448 EXPECT_TRUE(OpenDocument("hello_world.pdf"));
449 FPDF_PAGE page = LoadPage(0);
thestig4997b222016-06-07 10:46:22 -0700450 EXPECT_TRUE(page);
Lei Zhang0f2ea022016-01-11 12:01:23 -0800451
452 FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
thestig4997b222016-06-07 10:46:22 -0700453 EXPECT_TRUE(textpage);
Lei Zhang0f2ea022016-01-11 12:01:23 -0800454
455 const double kExpectedFontsSizes[] = {12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
456 12, 12, 12, 1, 1, 16, 16, 16, 16, 16,
457 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
458
459 int count = FPDFText_CountChars(textpage);
Wei Li05d53f02016-03-29 16:42:53 -0700460 ASSERT_EQ(FX_ArraySize(kExpectedFontsSizes), static_cast<size_t>(count));
Lei Zhang0f2ea022016-01-11 12:01:23 -0800461 for (int i = 0; i < count; ++i)
462 EXPECT_EQ(kExpectedFontsSizes[i], FPDFText_GetFontSize(textpage, i)) << i;
463
464 FPDFText_ClosePage(textpage);
465 UnloadPage(page);
466}
npm84be3a32016-09-15 13:27:21 -0700467
468TEST_F(FPDFTextEmbeddertest, ToUnicode) {
469 EXPECT_TRUE(OpenDocument("bug_583.pdf"));
470 FPDF_PAGE page = LoadPage(0);
471 EXPECT_TRUE(page);
472
473 FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
474 EXPECT_TRUE(textpage);
475
476 ASSERT_EQ(1, FPDFText_CountChars(textpage));
477 EXPECT_EQ(static_cast<unsigned int>(0), FPDFText_GetUnicode(textpage, 0));
478
479 FPDFText_ClosePage(textpage);
480 UnloadPage(page);
481}