blob: 3d496bc06fb90df6c81254a2de04690de55044de [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
dsinclaira52ab742016-09-29 13:59:29 -07007#include "core/fxcrt/fx_basic.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
Nico Weber9d8ec5a2015-08-04 13:00:21 -070074 EXPECT_EQ(4, FPDFText_GetCharIndexAtPos(textpage, 42.0, 50.0, 1.0, 1.0));
75 EXPECT_EQ(-1, FPDFText_GetCharIndexAtPos(textpage, 0.0, 0.0, 1.0, 1.0));
76 EXPECT_EQ(-1, FPDFText_GetCharIndexAtPos(textpage, 199.0, 199.0, 1.0, 1.0));
Tom Sepez526f6d52015-01-28 15:49:13 -080077
78 // Test out of range indicies.
Nico Weber9d8ec5a2015-08-04 13:00:21 -070079 EXPECT_EQ(-1,
80 FPDFText_GetCharIndexAtPos(textpage, 42.0, 10000000.0, 1.0, 1.0));
81 EXPECT_EQ(-1, FPDFText_GetCharIndexAtPos(textpage, -1.0, 50.0, 1.0, 1.0));
Tom Sepez526f6d52015-01-28 15:49:13 -080082
83 // Count does not include the terminating NUL in the string literal.
84 EXPECT_EQ(2, FPDFText_CountRects(textpage, 0, sizeof(expected) - 1));
85
86 left = 0.0;
87 right = 0.0;
88 bottom = 0.0;
89 top = 0.0;
90 FPDFText_GetRect(textpage, 1, &left, &top, &right, &bottom);
91 EXPECT_NEAR(20.847, left, 0.001);
92 EXPECT_NEAR(135.167, right, 0.001);
93 EXPECT_NEAR(96.655, bottom, 0.001);
94 EXPECT_NEAR(116.000, top, 0.001);
95
96 // Test out of range indicies set outputs to (0.0, 0.0, 0.0, 0.0).
97 left = -1.0;
98 right = -1.0;
99 bottom = -1.0;
100 top = -1.0;
101 FPDFText_GetRect(textpage, -1, &left, &top, &right, &bottom);
102 EXPECT_EQ(0.0, left);
103 EXPECT_EQ(0.0, right);
104 EXPECT_EQ(0.0, bottom);
105 EXPECT_EQ(0.0, top);
106
107 left = -2.0;
108 right = -2.0;
109 bottom = -2.0;
110 top = -2.0;
111 FPDFText_GetRect(textpage, 2, &left, &top, &right, &bottom);
112 EXPECT_EQ(0.0, left);
113 EXPECT_EQ(0.0, right);
114 EXPECT_EQ(0.0, bottom);
115 EXPECT_EQ(0.0, top);
116
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700117 EXPECT_EQ(9, FPDFText_GetBoundedText(textpage, 41.0, 56.0, 82.0, 48.0, 0, 0));
Tom Sepez526f6d52015-01-28 15:49:13 -0800118
119 // Extract starting at character 4 as above.
120 memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700121 EXPECT_EQ(1, FPDFText_GetBoundedText(textpage, 41.0, 56.0, 82.0, 48.0,
122 fixed_buffer, 1));
Tom Sepez526f6d52015-01-28 15:49:13 -0800123 EXPECT_TRUE(check_unsigned_shorts(expected + 4, fixed_buffer, 1));
124 EXPECT_EQ(0xbdbd, fixed_buffer[1]);
125
126 memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127 EXPECT_EQ(9, FPDFText_GetBoundedText(textpage, 41.0, 56.0, 82.0, 48.0,
128 fixed_buffer, 9));
Tom Sepez526f6d52015-01-28 15:49:13 -0800129 EXPECT_TRUE(check_unsigned_shorts(expected + 4, fixed_buffer, 9));
130 EXPECT_EQ(0xbdbd, fixed_buffer[9]);
131
132 memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
Oliver Chang35e68a52015-12-09 12:44:33 -0800133 EXPECT_EQ(10, FPDFText_GetBoundedText(textpage, 41.0, 56.0, 82.0, 48.0,
134 fixed_buffer, 128));
Tom Sepez526f6d52015-01-28 15:49:13 -0800135 EXPECT_TRUE(check_unsigned_shorts(expected + 4, fixed_buffer, 9));
Oliver Chang35e68a52015-12-09 12:44:33 -0800136 EXPECT_EQ(0u, fixed_buffer[9]);
137 EXPECT_EQ(0xbdbd, fixed_buffer[10]);
Tom Sepez526f6d52015-01-28 15:49:13 -0800138
139 FPDFText_ClosePage(textpage);
Lei Zhangd27acae2015-05-15 15:36:02 -0700140 UnloadPage(page);
Tom Sepez526f6d52015-01-28 15:49:13 -0800141}
142
143TEST_F(FPDFTextEmbeddertest, TextSearch) {
Wei Li091f7a02015-11-09 12:09:55 -0800144 EXPECT_TRUE(OpenDocument("hello_world.pdf"));
Tom Sepezda8189e2015-01-30 14:41:50 -0800145 FPDF_PAGE page = LoadPage(0);
thestig4997b222016-06-07 10:46:22 -0700146 EXPECT_TRUE(page);
Tom Sepez526f6d52015-01-28 15:49:13 -0800147
148 FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
thestig4997b222016-06-07 10:46:22 -0700149 EXPECT_TRUE(textpage);
Tom Sepez526f6d52015-01-28 15:49:13 -0800150
Tom Sepez0aa35312016-01-06 10:16:32 -0800151 std::unique_ptr<unsigned short, pdfium::FreeDeleter> nope =
152 GetFPDFWideString(L"nope");
153 std::unique_ptr<unsigned short, pdfium::FreeDeleter> world =
154 GetFPDFWideString(L"world");
155 std::unique_ptr<unsigned short, pdfium::FreeDeleter> world_caps =
156 GetFPDFWideString(L"WORLD");
157 std::unique_ptr<unsigned short, pdfium::FreeDeleter> world_substr =
158 GetFPDFWideString(L"orld");
Tom Sepez526f6d52015-01-28 15:49:13 -0800159
160 // No occurences of "nope" in test page.
Tom Sepez0aa35312016-01-06 10:16:32 -0800161 FPDF_SCHHANDLE search = FPDFText_FindStart(textpage, nope.get(), 0, 0);
thestig4997b222016-06-07 10:46:22 -0700162 EXPECT_TRUE(search);
Tom Sepez526f6d52015-01-28 15:49:13 -0800163 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
164 EXPECT_EQ(0, FPDFText_GetSchCount(search));
165
166 // Advancing finds nothing.
167 EXPECT_FALSE(FPDFText_FindNext(search));
168 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
169 EXPECT_EQ(0, FPDFText_GetSchCount(search));
170
171 // Retreating finds nothing.
172 EXPECT_FALSE(FPDFText_FindPrev(search));
173 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
174 EXPECT_EQ(0, FPDFText_GetSchCount(search));
175 FPDFText_FindClose(search);
176
177 // Two occurences of "world" in test page.
Tom Sepez0aa35312016-01-06 10:16:32 -0800178 search = FPDFText_FindStart(textpage, world.get(), 0, 2);
thestig4997b222016-06-07 10:46:22 -0700179 EXPECT_TRUE(search);
Tom Sepez526f6d52015-01-28 15:49:13 -0800180
181 // Remains not found until advanced.
182 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
183 EXPECT_EQ(0, FPDFText_GetSchCount(search));
184
185 // First occurence of "world" in this test page.
186 EXPECT_TRUE(FPDFText_FindNext(search));
187 EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
188 EXPECT_EQ(5, FPDFText_GetSchCount(search));
189
190 // Last occurence of "world" in this test page.
191 EXPECT_TRUE(FPDFText_FindNext(search));
192 EXPECT_EQ(24, FPDFText_GetSchResultIndex(search));
193 EXPECT_EQ(5, FPDFText_GetSchCount(search));
194
195 // Found position unchanged when fails to advance.
196 EXPECT_FALSE(FPDFText_FindNext(search));
197 EXPECT_EQ(24, FPDFText_GetSchResultIndex(search));
198 EXPECT_EQ(5, FPDFText_GetSchCount(search));
199
200 // Back to first occurence.
201 EXPECT_TRUE(FPDFText_FindPrev(search));
202 EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
203 EXPECT_EQ(5, FPDFText_GetSchCount(search));
204
205 // Found position unchanged when fails to retreat.
206 EXPECT_FALSE(FPDFText_FindPrev(search));
207 EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
208 EXPECT_EQ(5, FPDFText_GetSchCount(search));
209 FPDFText_FindClose(search);
210
211 // Exact search unaffected by case sensitiity and whole word flags.
Tom Sepez0aa35312016-01-06 10:16:32 -0800212 search = FPDFText_FindStart(textpage, world.get(),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700213 FPDF_MATCHCASE | FPDF_MATCHWHOLEWORD, 0);
thestig4997b222016-06-07 10:46:22 -0700214 EXPECT_TRUE(search);
Tom Sepez526f6d52015-01-28 15:49:13 -0800215 EXPECT_TRUE(FPDFText_FindNext(search));
216 EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
217 EXPECT_EQ(5, FPDFText_GetSchCount(search));
218 FPDFText_FindClose(search);
219
220 // Default is case-insensitive, so matching agaist caps works.
Tom Sepez0aa35312016-01-06 10:16:32 -0800221 search = FPDFText_FindStart(textpage, world_caps.get(), 0, 0);
thestig4997b222016-06-07 10:46:22 -0700222 EXPECT_TRUE(search);
Tom Sepez526f6d52015-01-28 15:49:13 -0800223 EXPECT_TRUE(FPDFText_FindNext(search));
224 EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
225 EXPECT_EQ(5, FPDFText_GetSchCount(search));
226 FPDFText_FindClose(search);
227
228 // But can be made case sensitive, in which case this fails.
Tom Sepez0aa35312016-01-06 10:16:32 -0800229 search = FPDFText_FindStart(textpage, world_caps.get(), FPDF_MATCHCASE, 0);
Tom Sepez526f6d52015-01-28 15:49:13 -0800230 EXPECT_FALSE(FPDFText_FindNext(search));
231 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
232 EXPECT_EQ(0, FPDFText_GetSchCount(search));
233 FPDFText_FindClose(search);
234
235 // Default is match anywhere within word, so matching substirng works.
Tom Sepez0aa35312016-01-06 10:16:32 -0800236 search = FPDFText_FindStart(textpage, world_substr.get(), 0, 0);
Tom Sepez526f6d52015-01-28 15:49:13 -0800237 EXPECT_TRUE(FPDFText_FindNext(search));
238 EXPECT_EQ(8, FPDFText_GetSchResultIndex(search));
239 EXPECT_EQ(4, FPDFText_GetSchCount(search));
240 FPDFText_FindClose(search);
241
242 // But can be made to mach word boundaries, in which case this fails.
Tom Sepez0aa35312016-01-06 10:16:32 -0800243 search =
244 FPDFText_FindStart(textpage, world_substr.get(), FPDF_MATCHWHOLEWORD, 0);
Tom Sepez526f6d52015-01-28 15:49:13 -0800245 EXPECT_FALSE(FPDFText_FindNext(search));
246 // TODO(tsepez): investigate strange index/count values in this state.
247 FPDFText_FindClose(search);
248
249 FPDFText_ClosePage(textpage);
Lei Zhangd27acae2015-05-15 15:36:02 -0700250 UnloadPage(page);
Tom Sepez526f6d52015-01-28 15:49:13 -0800251}
252
Tom Sepez26b8a5b2015-01-27 12:42:36 -0800253// Test that the page has characters despite a bad stream length.
254TEST_F(FPDFTextEmbeddertest, StreamLengthPastEndOfFile) {
Wei Li091f7a02015-11-09 12:09:55 -0800255 EXPECT_TRUE(OpenDocument("bug_57.pdf"));
Tom Sepezda8189e2015-01-30 14:41:50 -0800256 FPDF_PAGE page = LoadPage(0);
thestig4997b222016-06-07 10:46:22 -0700257 EXPECT_TRUE(page);
Tom Sepez526f6d52015-01-28 15:49:13 -0800258
Tom Sepez26b8a5b2015-01-27 12:42:36 -0800259 FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
thestig4997b222016-06-07 10:46:22 -0700260 EXPECT_TRUE(textpage);
Tom Sepez26b8a5b2015-01-27 12:42:36 -0800261 EXPECT_EQ(13, FPDFText_CountChars(textpage));
Tom Sepez526f6d52015-01-28 15:49:13 -0800262
263 FPDFText_ClosePage(textpage);
Lei Zhangd27acae2015-05-15 15:36:02 -0700264 UnloadPage(page);
Tom Sepez526f6d52015-01-28 15:49:13 -0800265}
266
267TEST_F(FPDFTextEmbeddertest, WebLinks) {
Wei Li091f7a02015-11-09 12:09:55 -0800268 EXPECT_TRUE(OpenDocument("weblinks.pdf"));
Tom Sepezda8189e2015-01-30 14:41:50 -0800269 FPDF_PAGE page = LoadPage(0);
thestig4997b222016-06-07 10:46:22 -0700270 EXPECT_TRUE(page);
Tom Sepez526f6d52015-01-28 15:49:13 -0800271
272 FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
thestig4997b222016-06-07 10:46:22 -0700273 EXPECT_TRUE(textpage);
Tom Sepez526f6d52015-01-28 15:49:13 -0800274
275 FPDF_PAGELINK pagelink = FPDFLink_LoadWebLinks(textpage);
thestig4997b222016-06-07 10:46:22 -0700276 EXPECT_TRUE(pagelink);
Tom Sepez526f6d52015-01-28 15:49:13 -0800277
278 // Page contains two HTTP-style URLs.
279 EXPECT_EQ(2, FPDFLink_CountWebLinks(pagelink));
280
Oliver Chang35e68a52015-12-09 12:44:33 -0800281 // Only a terminating NUL required for bogus links.
282 EXPECT_EQ(1, FPDFLink_GetURL(pagelink, 2, nullptr, 0));
283 EXPECT_EQ(1, FPDFLink_GetURL(pagelink, 1400, nullptr, 0));
284 EXPECT_EQ(1, FPDFLink_GetURL(pagelink, -1, nullptr, 0));
Tom Sepez526f6d52015-01-28 15:49:13 -0800285
286 // Query the number of characters required for each link (incl NUL).
Oliver Chang35e68a52015-12-09 12:44:33 -0800287 EXPECT_EQ(25, FPDFLink_GetURL(pagelink, 0, nullptr, 0));
288 EXPECT_EQ(26, FPDFLink_GetURL(pagelink, 1, nullptr, 0));
Tom Sepez526f6d52015-01-28 15:49:13 -0800289
Lei Zhangd27acae2015-05-15 15:36:02 -0700290 static const char expected_url[] = "http://example.com?q=foo";
Wei Li05d53f02016-03-29 16:42:53 -0700291 static const size_t expected_len = sizeof(expected_url);
Tom Sepez526f6d52015-01-28 15:49:13 -0800292 unsigned short fixed_buffer[128];
293
294 // Retrieve a link with too small a buffer. Buffer will not be
295 // NUL-terminated, but must not be modified past indicated length,
296 // so pre-fill with a pattern to check write bounds.
297 memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
298 EXPECT_EQ(1, FPDFLink_GetURL(pagelink, 0, fixed_buffer, 1));
299 EXPECT_TRUE(check_unsigned_shorts(expected_url, fixed_buffer, 1));
300 EXPECT_EQ(0xbdbd, fixed_buffer[1]);
301
302 // Check buffer that doesn't have space for a terminating NUL.
303 memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
Wei Li05d53f02016-03-29 16:42:53 -0700304 EXPECT_EQ(static_cast<int>(expected_len - 1),
305 FPDFLink_GetURL(pagelink, 0, fixed_buffer, expected_len - 1));
306 EXPECT_TRUE(
307 check_unsigned_shorts(expected_url, fixed_buffer, expected_len - 1));
308 EXPECT_EQ(0xbdbd, fixed_buffer[expected_len - 1]);
Tom Sepez526f6d52015-01-28 15:49:13 -0800309
310 // Retreive link with exactly-sized buffer.
311 memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
Wei Li05d53f02016-03-29 16:42:53 -0700312 EXPECT_EQ(static_cast<int>(expected_len),
313 FPDFLink_GetURL(pagelink, 0, fixed_buffer, expected_len));
314 EXPECT_TRUE(check_unsigned_shorts(expected_url, fixed_buffer, expected_len));
315 EXPECT_EQ(0u, fixed_buffer[expected_len - 1]);
316 EXPECT_EQ(0xbdbd, fixed_buffer[expected_len]);
Tom Sepez526f6d52015-01-28 15:49:13 -0800317
318 // Retreive link with ample-sized-buffer.
319 memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
Wei Li05d53f02016-03-29 16:42:53 -0700320 EXPECT_EQ(static_cast<int>(expected_len),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700321 FPDFLink_GetURL(pagelink, 0, fixed_buffer, 128));
Wei Li05d53f02016-03-29 16:42:53 -0700322 EXPECT_TRUE(check_unsigned_shorts(expected_url, fixed_buffer, expected_len));
323 EXPECT_EQ(0u, fixed_buffer[expected_len - 1]);
324 EXPECT_EQ(0xbdbd, fixed_buffer[expected_len]);
Tom Sepez526f6d52015-01-28 15:49:13 -0800325
326 // Each link rendered in a single rect in this test page.
327 EXPECT_EQ(1, FPDFLink_CountRects(pagelink, 0));
328 EXPECT_EQ(1, FPDFLink_CountRects(pagelink, 1));
329
330 // Each link rendered in a single rect in this test page.
331 EXPECT_EQ(0, FPDFLink_CountRects(pagelink, -1));
332 EXPECT_EQ(0, FPDFLink_CountRects(pagelink, 2));
333 EXPECT_EQ(0, FPDFLink_CountRects(pagelink, 10000));
334
335 // Check boundary of valid link index with valid rect index.
336 double left = 0.0;
337 double right = 0.0;
338 double top = 0.0;
339 double bottom = 0.0;
340 FPDFLink_GetRect(pagelink, 0, 0, &left, &top, &right, &bottom);
341 EXPECT_NEAR(50.791, left, 0.001);
342 EXPECT_NEAR(187.963, right, 0.001);
343 EXPECT_NEAR(97.624, bottom, 0.001);
344 EXPECT_NEAR(108.736, top, 0.001);
345
346 // Check that valid link with invalid rect index leaves parameters unchanged.
347 left = -1.0;
348 right = -1.0;
349 top = -1.0;
350 bottom = -1.0;
351 FPDFLink_GetRect(pagelink, 0, 1, &left, &top, &right, &bottom);
352 EXPECT_EQ(-1.0, left);
353 EXPECT_EQ(-1.0, right);
354 EXPECT_EQ(-1.0, bottom);
355 EXPECT_EQ(-1.0, top);
356
357 // Check that invalid link index leaves parameters unchanged.
358 left = -2.0;
359 right = -2.0;
360 top = -2.0;
361 bottom = -2.0;
362 FPDFLink_GetRect(pagelink, -1, 0, &left, &top, &right, &bottom);
363 EXPECT_EQ(-2.0, left);
364 EXPECT_EQ(-2.0, right);
365 EXPECT_EQ(-2.0, bottom);
366 EXPECT_EQ(-2.0, top);
367
368 FPDFLink_CloseWebLinks(pagelink);
369 FPDFText_ClosePage(textpage);
Lei Zhangd27acae2015-05-15 15:36:02 -0700370 UnloadPage(page);
Tom Sepez26b8a5b2015-01-27 12:42:36 -0800371}
Lei Zhang0f2ea022016-01-11 12:01:23 -0800372
Wei Li76309072017-03-16 17:31:03 -0700373TEST_F(FPDFTextEmbeddertest, WebLinksAcrossLines) {
374 EXPECT_TRUE(OpenDocument("weblinks_across_lines.pdf"));
375 FPDF_PAGE page = LoadPage(0);
376 EXPECT_TRUE(page);
377
378 FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
379 EXPECT_TRUE(textpage);
380
381 FPDF_PAGELINK pagelink = FPDFLink_LoadWebLinks(textpage);
382 EXPECT_TRUE(pagelink);
383
384 static const char* const kExpectedUrls[] = {
385 "http://example.com?", // from "http://www.example.com?\r\nfoo"
386 "http://example.com/", // from "http://www.example.com/\r\nfoo"
387 "http://example.com/test-foo", // from "http://example.com/test-\r\nfoo"
388 "http://abc.com/test-foo", // from "http://abc.com/test-\r\n\r\nfoo"
389 // Next two links from "http://www.example.com/\r\nhttp://www.abc.com/"
390 "http://example.com/", "http://www.abc.com",
391 };
392 static const int kNumLinks = static_cast<int>(FX_ArraySize(kExpectedUrls));
393
394 EXPECT_EQ(kNumLinks, FPDFLink_CountWebLinks(pagelink));
395
396 unsigned short fixed_buffer[128];
397 for (int i = 0; i < kNumLinks; i++) {
398 const size_t expected_len = strlen(kExpectedUrls[i]) + 1;
399 memset(fixed_buffer, 0, FX_ArraySize(fixed_buffer));
400 EXPECT_EQ(static_cast<int>(expected_len),
401 FPDFLink_GetURL(pagelink, i, nullptr, 0));
402 EXPECT_EQ(
403 static_cast<int>(expected_len),
404 FPDFLink_GetURL(pagelink, i, fixed_buffer, FX_ArraySize(fixed_buffer)));
405 EXPECT_TRUE(
406 check_unsigned_shorts(kExpectedUrls[i], fixed_buffer, expected_len));
407 }
408
409 FPDFLink_CloseWebLinks(pagelink);
410 FPDFText_ClosePage(textpage);
411 UnloadPage(page);
412}
413
414TEST_F(FPDFTextEmbeddertest, WebLinksAcrossLinesBug) {
415 EXPECT_TRUE(OpenDocument("bug_650.pdf"));
416 FPDF_PAGE page = LoadPage(0);
417 EXPECT_TRUE(page);
418
419 FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
420 EXPECT_TRUE(textpage);
421
422 FPDF_PAGELINK pagelink = FPDFLink_LoadWebLinks(textpage);
423 EXPECT_TRUE(pagelink);
424
425 EXPECT_EQ(2, FPDFLink_CountWebLinks(pagelink));
426 unsigned short fixed_buffer[128] = {0};
427 static const char kExpectedUrl[] =
428 "http://tutorial45.com/learn-autocad-basics-day-166/";
429 static const int kUrlSize = static_cast<int>(sizeof(kExpectedUrl));
430
431 EXPECT_EQ(kUrlSize, FPDFLink_GetURL(pagelink, 1, nullptr, 0));
432 EXPECT_EQ(kUrlSize, FPDFLink_GetURL(pagelink, 1, fixed_buffer,
433 FX_ArraySize(fixed_buffer)));
434 EXPECT_TRUE(check_unsigned_shorts(kExpectedUrl, fixed_buffer, kUrlSize));
435
436 FPDFLink_CloseWebLinks(pagelink);
437 FPDFText_ClosePage(textpage);
438 UnloadPage(page);
439}
440
Lei Zhang0f2ea022016-01-11 12:01:23 -0800441TEST_F(FPDFTextEmbeddertest, GetFontSize) {
442 EXPECT_TRUE(OpenDocument("hello_world.pdf"));
443 FPDF_PAGE page = LoadPage(0);
thestig4997b222016-06-07 10:46:22 -0700444 EXPECT_TRUE(page);
Lei Zhang0f2ea022016-01-11 12:01:23 -0800445
446 FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
thestig4997b222016-06-07 10:46:22 -0700447 EXPECT_TRUE(textpage);
Lei Zhang0f2ea022016-01-11 12:01:23 -0800448
449 const double kExpectedFontsSizes[] = {12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
450 12, 12, 12, 1, 1, 16, 16, 16, 16, 16,
451 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
452
453 int count = FPDFText_CountChars(textpage);
Wei Li05d53f02016-03-29 16:42:53 -0700454 ASSERT_EQ(FX_ArraySize(kExpectedFontsSizes), static_cast<size_t>(count));
Lei Zhang0f2ea022016-01-11 12:01:23 -0800455 for (int i = 0; i < count; ++i)
456 EXPECT_EQ(kExpectedFontsSizes[i], FPDFText_GetFontSize(textpage, i)) << i;
457
458 FPDFText_ClosePage(textpage);
459 UnloadPage(page);
460}
npm84be3a32016-09-15 13:27:21 -0700461
462TEST_F(FPDFTextEmbeddertest, ToUnicode) {
463 EXPECT_TRUE(OpenDocument("bug_583.pdf"));
464 FPDF_PAGE page = LoadPage(0);
465 EXPECT_TRUE(page);
466
467 FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
468 EXPECT_TRUE(textpage);
469
470 ASSERT_EQ(1, FPDFText_CountChars(textpage));
471 EXPECT_EQ(static_cast<unsigned int>(0), FPDFText_GetUnicode(textpage, 0));
472
473 FPDFText_ClosePage(textpage);
474 UnloadPage(page);
475}