10#include "build/build_config.h"
11#include "core/fxcrt/compiler_specific.h"
12#include "core/fxcrt/stl_util.h"
13#include "core/fxge/fx_font.h"
14#include "public/cpp/fpdf_scopers.h"
15#include "public/fpdf_doc.h"
16#include "public/fpdf_text.h"
17#include "public/fpdf_transformpage.h"
18#include "public/fpdfview.h"
19#include "testing/embedder_test.h"
20#include "testing/fx_string_testhelpers.h"
21#include "testing/gmock/include/gmock/gmock.h"
22#include "testing/gtest/include/gtest/gtest.h"
24using ::testing::ElementsAreArray;
28constexpr char kHelloGoodbyeText[] =
"Hello, world!\r\nGoodbye, world!";
29constexpr int kHelloGoodbyeTextSize =
std::size(kHelloGoodbyeText);
31bool check_unsigned_shorts(
const char* expected,
32 const unsigned short* actual,
34 if (length > strlen(expected) + 1)
37 for (size_t i = 0; i < length; ++i) {
39 static_cast<
unsigned short>(
UNSAFE_TODO(expected[i]))) {
51 ASSERT_TRUE(OpenDocument(
"hello_world.pdf"));
52 FPDF_PAGE page = LoadPage(0);
56 ASSERT_TRUE(textpage);
58 unsigned short buffer[128];
59 fxcrt::Fill(buffer, 0xbdbd);
66 EXPECT_EQ(0, buffer[0]);
69 fxcrt::Fill(buffer, 0xbdbd);
71 EXPECT_EQ(kHelloGoodbyeText[0], buffer[0]);
72 EXPECT_EQ(0, buffer[1]);
76 ASSERT_EQ(kHelloGoodbyeTextSize, num_chars);
78 check_unsigned_shorts(kHelloGoodbyeText, buffer, kHelloGoodbyeTextSize));
82 for (size_t i = 0; i < kHelloGoodbyeTextSize - 1; ++i) {
83 EXPECT_EQ(
static_cast<
unsigned int>(
UNSAFE_TODO(kHelloGoodbyeText[i])),
84 FPDFText_GetUnicode(textpage, i))
91 static const char kSmallExpected[] =
"Hello";
92 unsigned short small_buffer[12];
93 fxcrt::Fill(buffer, 0xbdbd);
95 EXPECT_TRUE(check_unsigned_shorts(kSmallExpected, small_buffer,
96 sizeof(kSmallExpected)));
106 EXPECT_DOUBLE_EQ(1.0, left);
107 EXPECT_DOUBLE_EQ(2.0, right);
108 EXPECT_DOUBLE_EQ(3.0, bottom);
109 EXPECT_DOUBLE_EQ(4.0, top);
111 EXPECT_DOUBLE_EQ(1.0, left);
112 EXPECT_DOUBLE_EQ(2.0, right);
113 EXPECT_DOUBLE_EQ(3.0, bottom);
114 EXPECT_DOUBLE_EQ(4.0, top);
116 EXPECT_DOUBLE_EQ(1.0, left);
117 EXPECT_DOUBLE_EQ(2.0, right);
118 EXPECT_DOUBLE_EQ(3.0, bottom);
119 EXPECT_DOUBLE_EQ(4.0, top);
130 EXPECT_NEAR(41.120, left, 0.001);
131 EXPECT_NEAR(46.208, right, 0.001);
132 EXPECT_NEAR(49.892, bottom, 0.001);
133 EXPECT_NEAR(55.652, top, 0.001);
135 FS_RECTF rect = {4.0f, 1.0f, 3.0f, 2.0f};
137 EXPECT_FLOAT_EQ(4.0f, rect.left);
138 EXPECT_FLOAT_EQ(3.0f, rect.right);
139 EXPECT_FLOAT_EQ(2.0f, rect.bottom);
140 EXPECT_FLOAT_EQ(1.0f, rect.top);
142 EXPECT_FLOAT_EQ(4.0f, rect.left);
143 EXPECT_FLOAT_EQ(3.0f, rect.right);
144 EXPECT_FLOAT_EQ(2.0f, rect.bottom);
145 EXPECT_FLOAT_EQ(1.0f, rect.top);
147 EXPECT_FLOAT_EQ(4.0f, rect.left);
148 EXPECT_FLOAT_EQ(3.0f, rect.right);
149 EXPECT_FLOAT_EQ(2.0f, rect.bottom);
150 EXPECT_FLOAT_EQ(1.0f, rect.top);
154 EXPECT_FLOAT_EQ(40.664001f, rect.left);
155 EXPECT_FLOAT_EQ(46.664001f, rect.right);
156 EXPECT_FLOAT_EQ(47.667271f, rect.bottom);
157 EXPECT_FLOAT_EQ(59.667271f, rect.top);
162 EXPECT_NEAR(40.664, x, 0.001);
163 EXPECT_NEAR(50.000, y, 0.001);
182 EXPECT_NEAR(20.800, left, 0.001);
183 EXPECT_NEAR(135.040, right, 0.001);
184 EXPECT_NEAR(96.688, bottom, 0.001);
185 EXPECT_NEAR(111.600, top, 0.001);
193 EXPECT_EQ(0.0, left);
194 EXPECT_EQ(0.0, right);
195 EXPECT_EQ(0.0, bottom);
203 EXPECT_EQ(0.0, left);
204 EXPECT_EQ(0.0, right);
205 EXPECT_EQ(0.0, bottom);
212 fxcrt::Fill(buffer, 0xbdbd);
216 check_unsigned_shorts(
UNSAFE_TODO(kHelloGoodbyeText + 4), buffer, 1));
217 EXPECT_EQ(0xbdbd, buffer[1]);
219 fxcrt::Fill(buffer, 0xbdbd);
223 check_unsigned_shorts(
UNSAFE_TODO(kHelloGoodbyeText + 4), buffer, 8));
224 EXPECT_EQ(0xbdbd, buffer[9]);
226 fxcrt::Fill(buffer, 0xbdbd);
230 check_unsigned_shorts(
UNSAFE_TODO(kHelloGoodbyeText + 4), buffer, 9));
231 EXPECT_EQ(0u, buffer[9]);
232 EXPECT_EQ(0xbdbd, buffer[10]);
239 ASSERT_TRUE(OpenDocument(
"vertical_text.pdf"));
240 FPDF_PAGE page = LoadPage(0);
244 ASSERT_TRUE(textpage);
251 EXPECT_NEAR(6.664, x, 0.001);
252 EXPECT_NEAR(171.508, y, 0.001);
255 EXPECT_NEAR(8.668, x, 0.001);
256 EXPECT_NEAR(160.492, y, 0.001);
260 EXPECT_NEAR(4, rect.left, 0.001);
261 EXPECT_NEAR(16, rect.right, 0.001);
262 EXPECT_NEAR(178.984, rect.bottom, 0.001);
263 EXPECT_NEAR(170.308, rect.top, 0.001);
266 EXPECT_NEAR(4, rect.left, 0.001);
267 EXPECT_NEAR(16, rect.right, 0.001);
268 EXPECT_NEAR(170.308, rect.bottom, 0.001);
269 EXPECT_NEAR(159.292, rect.top, 0.001);
276 ASSERT_TRUE(OpenDocument(
"hebrew_mirrored.pdf"));
277 ScopedEmbedderTestPage page = LoadScopedPage(0);
280 ScopedFPDFTextPage textpage(FPDFText_LoadPage(page.get()));
281 ASSERT_TRUE(textpage);
283 constexpr int kCharCount = 10;
284 ASSERT_EQ(kCharCount, FPDFText_CountChars(textpage.get()));
286 unsigned short buffer[kCharCount + 1];
287 fxcrt::Fill(buffer, 0x4242);
288 EXPECT_EQ(kCharCount + 1,
289 FPDFText_GetText(textpage.get(), 0, kCharCount, buffer));
290 EXPECT_EQ(0x05d1, buffer[0]);
291 EXPECT_EQ(0x05e0, buffer[1]);
292 EXPECT_EQ(0x05d9, buffer[2]);
293 EXPECT_EQ(0x05de, buffer[3]);
294 EXPECT_EQ(0x05d9, buffer[4]);
295 EXPECT_EQ(0x05df, buffer[5]);
296 EXPECT_EQ(0x000d, buffer[6]);
297 EXPECT_EQ(0x000a, buffer[7]);
298 EXPECT_EQ(0x05df, buffer[8]);
299 EXPECT_EQ(0x05d1, buffer[9]);
303 ASSERT_TRUE(OpenDocument(
"hello_world.pdf"));
304 FPDF_PAGE page = LoadPage(0);
308 ASSERT_TRUE(textpage);
317 ScopedFPDFTextFind search(FPDFText_FindStart(textpage, nope.get(), 0, 0));
319 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
320 EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
323 EXPECT_FALSE(FPDFText_FindNext(search.get()));
324 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
325 EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
328 EXPECT_FALSE(FPDFText_FindPrev(search.get()));
329 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
330 EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
335 ScopedFPDFTextFind search(FPDFText_FindStart(textpage, world.get(), 0, 2));
339 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
340 EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
343 EXPECT_TRUE(FPDFText_FindNext(search.get()));
344 EXPECT_EQ(7, FPDFText_GetSchResultIndex(search.get()));
345 EXPECT_EQ(5, FPDFText_GetSchCount(search.get()));
348 EXPECT_TRUE(FPDFText_FindNext(search.get()));
349 EXPECT_EQ(24, FPDFText_GetSchResultIndex(search.get()));
350 EXPECT_EQ(5, FPDFText_GetSchCount(search.get()));
353 EXPECT_FALSE(FPDFText_FindNext(search.get()));
354 EXPECT_EQ(24, FPDFText_GetSchResultIndex(search.get()));
355 EXPECT_EQ(5, FPDFText_GetSchCount(search.get()));
358 EXPECT_TRUE(FPDFText_FindPrev(search.get()));
359 EXPECT_EQ(7, FPDFText_GetSchResultIndex(search.get()));
360 EXPECT_EQ(5, FPDFText_GetSchCount(search.get()));
363 EXPECT_FALSE(FPDFText_FindPrev(search.get()));
364 EXPECT_EQ(7, FPDFText_GetSchResultIndex(search.get()));
365 EXPECT_EQ(5, FPDFText_GetSchCount(search.get()));
370 ScopedFPDFTextFind search(FPDFText_FindStart(
373 EXPECT_TRUE(FPDFText_FindNext(search.get()));
374 EXPECT_EQ(7, FPDFText_GetSchResultIndex(search.get()));
375 EXPECT_EQ(5, FPDFText_GetSchCount(search.get()));
380 ScopedFPDFTextFind search(
381 FPDFText_FindStart(textpage, world_caps.get(), 0, 0));
383 EXPECT_TRUE(FPDFText_FindNext(search.get()));
384 EXPECT_EQ(7, FPDFText_GetSchResultIndex(search.get()));
385 EXPECT_EQ(5, FPDFText_GetSchCount(search.get()));
390 ScopedFPDFTextFind search(
391 FPDFText_FindStart(textpage, world_caps.get(),
FPDF_MATCHCASE, 0));
392 EXPECT_FALSE(FPDFText_FindNext(search.get()));
393 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
394 EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
399 ScopedFPDFTextFind search(
400 FPDFText_FindStart(textpage, world_substr.get(), 0, 0));
401 EXPECT_TRUE(FPDFText_FindNext(search.get()));
402 EXPECT_EQ(8, FPDFText_GetSchResultIndex(search.get()));
403 EXPECT_EQ(4, FPDFText_GetSchCount(search.get()));
408 ScopedFPDFTextFind search(FPDFText_FindStart(textpage, world_substr.get(),
410 EXPECT_FALSE(FPDFText_FindNext(search.get()));
419 ASSERT_TRUE(OpenDocument(
"find_text_consecutive.pdf"));
420 FPDF_PAGE page = LoadPage(0);
424 ASSERT_TRUE(textpage);
430 ScopedFPDFTextFind search(FPDFText_FindStart(textpage, aaaa.get(), 0, 0));
434 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
435 EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
438 EXPECT_TRUE(FPDFText_FindNext(search.get()));
439 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
440 EXPECT_EQ(4, FPDFText_GetSchCount(search.get()));
443 EXPECT_TRUE(FPDFText_FindNext(search.get()));
444 EXPECT_EQ(4, FPDFText_GetSchResultIndex(search.get()));
445 EXPECT_EQ(4, FPDFText_GetSchCount(search.get()));
448 EXPECT_FALSE(FPDFText_FindNext(search.get()));
449 EXPECT_EQ(4, FPDFText_GetSchResultIndex(search.get()));
450 EXPECT_EQ(4, FPDFText_GetSchCount(search.get()));
453 EXPECT_TRUE(FPDFText_FindPrev(search.get()));
454 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
455 EXPECT_EQ(4, FPDFText_GetSchCount(search.get()));
458 EXPECT_FALSE(FPDFText_FindPrev(search.get()));
459 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
460 EXPECT_EQ(4, FPDFText_GetSchCount(search.get()));
466 ScopedFPDFTextFind search(
471 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
472 EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
475 for (
int i = 0; i < 7; ++i) {
476 EXPECT_TRUE(FPDFText_FindNext(search.get()));
477 EXPECT_EQ(i, FPDFText_GetSchResultIndex(search.get()));
478 EXPECT_EQ(4, FPDFText_GetSchCount(search.get()));
482 EXPECT_FALSE(FPDFText_FindNext(search.get()));
483 EXPECT_EQ(6, FPDFText_GetSchResultIndex(search.get()));
484 EXPECT_EQ(4, FPDFText_GetSchCount(search.get()));
486 for (
int i = 5; i >= 0; --i) {
487 EXPECT_TRUE(FPDFText_FindPrev(search.get()));
488 EXPECT_EQ(i, FPDFText_GetSchResultIndex(search.get()));
489 EXPECT_EQ(4, FPDFText_GetSchCount(search.get()));
493 EXPECT_FALSE(FPDFText_FindPrev(search.get()));
494 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
495 EXPECT_EQ(4, FPDFText_GetSchCount(search.get()));
503 ASSERT_TRUE(OpenDocument(
"hello_world.pdf"));
504 ScopedEmbedderTestPage page = LoadScopedPage(0);
507 ScopedFPDFTextPage textpage(FPDFText_LoadPage(page.get()));
508 ASSERT_TRUE(textpage);
511 ScopedFPDFTextFind search(
512 FPDFText_FindStart(textpage.get(), search_term.get(), 0, 0));
514 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
515 EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
517 EXPECT_TRUE(FPDFText_FindNext(search.get()));
518 EXPECT_EQ(7, FPDFText_GetSchResultIndex(search.get()));
519 EXPECT_EQ(6, FPDFText_GetSchCount(search.get()));
521 EXPECT_TRUE(FPDFText_FindNext(search.get()));
522 EXPECT_EQ(24, FPDFText_GetSchResultIndex(search.get()));
523 EXPECT_EQ(6, FPDFText_GetSchCount(search.get()));
527 ASSERT_TRUE(OpenDocument(
"hello_world.pdf"));
528 ScopedEmbedderTestPage page = LoadScopedPage(0);
531 ScopedFPDFTextPage textpage(FPDFText_LoadPage(page.get()));
532 ASSERT_TRUE(textpage);
535 ScopedFPDFTextFind search(
536 FPDFText_FindStart(textpage.get(), search_term.get(), 0, 0));
538 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
539 EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
541 EXPECT_TRUE(FPDFText_FindNext(search.get()));
542 EXPECT_EQ(14, FPDFText_GetSchResultIndex(search.get()));
543 EXPECT_EQ(5, FPDFText_GetSchCount(search.get()));
545 EXPECT_FALSE(FPDFText_FindNext(search.get()));
549 ASSERT_TRUE(OpenDocument(
"hello_world.pdf"));
550 ScopedEmbedderTestPage page = LoadScopedPage(0);
553 ScopedFPDFTextPage textpage(FPDFText_LoadPage(page.get()));
554 ASSERT_TRUE(textpage);
557 ScopedFPDFTextFind search(
558 FPDFText_FindStart(textpage.get(), search_term.get(), 0, 0));
560 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
561 EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
563 EXPECT_TRUE(FPDFText_FindNext(search.get()));
564 EXPECT_EQ(10, FPDFText_GetSchResultIndex(search.get()));
565 EXPECT_EQ(4, FPDFText_GetSchCount(search.get()));
567 EXPECT_FALSE(FPDFText_FindNext(search.get()));
571 ASSERT_TRUE(OpenDocument(
"hello_world.pdf"));
572 ScopedEmbedderTestPage page = LoadScopedPage(0);
575 ScopedFPDFTextPage textpage(FPDFText_LoadPage(page.get()));
576 ASSERT_TRUE(textpage);
579 ScopedFPDFTextFind search(
580 FPDFText_FindStart(textpage.get(), search_term.get(), 0, 0));
582 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
583 EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
585 EXPECT_TRUE(FPDFText_FindNext(search.get()));
586 EXPECT_EQ(10, FPDFText_GetSchResultIndex(search.get()));
590 EXPECT_EQ(6, FPDFText_GetSchCount(search.get()));
592 EXPECT_FALSE(FPDFText_FindNext(search.get()));
597#define MAYBE_TextSearchLatinExtended DISABLED_TextSearchLatinExtended
599#define MAYBE_TextSearchLatinExtended TextSearchLatinExtended
602 ASSERT_TRUE(OpenDocument(
"latin_extended.pdf"));
603 FPDF_PAGE page = LoadPage(0);
607 ASSERT_TRUE(textpage);
610 constexpr FPDF_WCHAR kNeedleUpper[] = {0x0102, 0x0000};
611 constexpr FPDF_WCHAR kNeedleLower[] = {0x0103, 0x0000};
613 for (
const auto* needle : {kNeedleUpper, kNeedleLower}) {
614 ScopedFPDFTextFind search(FPDFText_FindStart(textpage, needle, 0, 0));
616 EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
617 EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
620 EXPECT_TRUE(FPDFText_FindNext(search.get()));
621 EXPECT_EQ(2, FPDFText_GetSchResultIndex(search.get()));
622 EXPECT_EQ(1, FPDFText_GetSchCount(search.get()));
623 EXPECT_TRUE(FPDFText_FindNext(search.get()));
624 EXPECT_EQ(3, FPDFText_GetSchResultIndex(search.get()));
625 EXPECT_EQ(1, FPDFText_GetSchCount(search.get()));
627 EXPECT_FALSE(FPDFText_FindNext(search.get()));
636 ASSERT_TRUE(OpenDocument(
"bug_57.pdf"));
637 FPDF_PAGE page = LoadPage(0);
641 ASSERT_TRUE(textpage);
649 ASSERT_TRUE(OpenDocument(
"weblinks.pdf"));
650 FPDF_PAGE page = LoadPage(0);
654 ASSERT_TRUE(textpage);
658 EXPECT_TRUE(pagelink);
661 EXPECT_EQ(2, FPDFLink_CountWebLinks(pagelink.get()));
664 EXPECT_EQ(1, FPDFLink_GetURL(pagelink.get(), 2,
nullptr, 0));
665 EXPECT_EQ(1, FPDFLink_GetURL(pagelink.get(), 1400,
nullptr, 0));
666 EXPECT_EQ(1, FPDFLink_GetURL(pagelink.get(), -1,
nullptr, 0));
670 EXPECT_TRUE(pagelink);
676 static const char expected_url[] =
"http://example.com?q=foo";
677 static const size_t expected_len =
sizeof(expected_url);
678 std::array<
unsigned short, 128> buffer;
683 fxcrt::Fill(buffer, 0xbdbd);
684 EXPECT_EQ(1, FPDFLink_GetURL(pagelink, 0, buffer.data(), 1));
685 EXPECT_TRUE(check_unsigned_shorts(expected_url, buffer.data(), 1));
686 EXPECT_EQ(0xbdbd, buffer[1]);
689 fxcrt::Fill(buffer, 0xbdbd);
690 EXPECT_EQ(
static_cast<
int>(expected_len - 1),
691 FPDFLink_GetURL(pagelink, 0, buffer.data(), expected_len - 1));
693 check_unsigned_shorts(expected_url, buffer.data(), expected_len - 1));
694 EXPECT_EQ(0xbdbd, buffer[expected_len - 1]);
697 fxcrt::Fill(buffer, 0xbdbd);
698 EXPECT_EQ(
static_cast<
int>(expected_len),
699 FPDFLink_GetURL(pagelink, 0, buffer.data(), expected_len));
700 EXPECT_TRUE(check_unsigned_shorts(expected_url, buffer.data(), expected_len));
701 EXPECT_EQ(0u, buffer[expected_len - 1]);
702 EXPECT_EQ(0xbdbd, buffer[expected_len]);
705 fxcrt::Fill(buffer, 0xbdbd);
706 EXPECT_EQ(
static_cast<
int>(expected_len),
707 FPDFLink_GetURL(pagelink, 0, buffer.data(), buffer.size()));
708 EXPECT_TRUE(check_unsigned_shorts(expected_url, buffer.data(), expected_len));
709 EXPECT_EQ(0u, buffer[expected_len - 1]);
710 EXPECT_EQ(0xbdbd, buffer[expected_len]);
727 EXPECT_NEAR(50.828, left, 0.001);
728 EXPECT_NEAR(187.904, right, 0.001);
729 EXPECT_NEAR(97.516, bottom, 0.001);
730 EXPECT_NEAR(108.700, top, 0.001);
738 EXPECT_EQ(-1.0, left);
739 EXPECT_EQ(-1.0, right);
740 EXPECT_EQ(-1.0, bottom);
741 EXPECT_EQ(-1.0, top);
749 EXPECT_EQ(-2.0, left);
750 EXPECT_EQ(-2.0, right);
751 EXPECT_EQ(-2.0, bottom);
752 EXPECT_EQ(-2.0, top);
760 ASSERT_TRUE(OpenDocument(
"weblinks_across_lines.pdf"));
761 FPDF_PAGE page = LoadPage(0);
765 ASSERT_TRUE(textpage);
768 EXPECT_TRUE(pagelink);
770 static constexpr auto kExpectedUrls =
fxcrt::ToArray<
const char*>({
771 "http://example.com",
772 "http://example.com/",
773 "http://example.com/test-foo",
774 "http://abc.com/test-foo",
776 "http://example.com/",
777 "http://www.abc.com",
779 static const int kNumLinks =
static_cast<
int>(
std::size(kExpectedUrls));
783 for (
int i = 0; i < kNumLinks; i++) {
784 unsigned short buffer[128] = {};
785 const size_t expected_len = strlen(kExpectedUrls[i]) + 1;
786 EXPECT_EQ(
static_cast<
int>(expected_len),
788 EXPECT_EQ(
static_cast<
int>(expected_len),
789 FPDFLink_GetURL(pagelink, i, buffer,
std::size(buffer)));
790 EXPECT_TRUE(check_unsigned_shorts(kExpectedUrls[i], buffer, expected_len));
799 ASSERT_TRUE(OpenDocument(
"bug_650.pdf"));
800 FPDF_PAGE page = LoadPage(0);
804 ASSERT_TRUE(textpage);
807 EXPECT_TRUE(pagelink);
810 unsigned short buffer[128] = {0};
811 static const char kExpectedUrl[] =
812 "http://tutorial45.com/learn-autocad-basics-day-166/";
813 static const int kUrlSize =
static_cast<
int>(
sizeof(kExpectedUrl));
816 EXPECT_EQ(kUrlSize, FPDFLink_GetURL(pagelink, 1, buffer,
std::size(buffer)));
817 EXPECT_TRUE(check_unsigned_shorts(kExpectedUrl, buffer, kUrlSize));
825 ASSERT_TRUE(OpenDocument(
"weblinks.pdf"));
826 FPDF_PAGE page = LoadPage(0);
830 ASSERT_TRUE(text_page);
833 EXPECT_TRUE(page_link);
836 int start_char_index;
840 EXPECT_EQ(35, start_char_index);
841 EXPECT_EQ(24, char_count);
844 start_char_index = -10;
848 EXPECT_EQ(start_char_index, -10);
849 EXPECT_EQ(char_count, -8);
852 start_char_index = -10;
856 EXPECT_EQ(start_char_index, -10);
857 EXPECT_EQ(char_count, -8);
860 start_char_index = -10;
864 EXPECT_EQ(start_char_index, -10);
865 EXPECT_EQ(char_count, -8);
873 ASSERT_TRUE(OpenDocument(
"annots.pdf"));
874 FPDF_PAGE page = LoadPage(0);
879 ASSERT_EQ(9, annot_count);
880 int annot_subtype_link_count = 0;
881 for (
int i = 0; i < annot_count; ++i) {
884 ++annot_subtype_link_count;
887 EXPECT_EQ(4, annot_subtype_link_count);
891 FPDF_LINK link_annot;
894 ASSERT_TRUE(link_annot);
895 if (start_pos == 1 || start_pos == 2) {
898 FPDF_DEST link_dest = FPDFLink_GetDest(document(), link_annot);
899 EXPECT_TRUE(link_dest);
900 EXPECT_EQ(start_pos - 1,
901 FPDFDest_GetDestPageIndex(document(), link_dest));
902 }
else if (start_pos == 3) {
905 EXPECT_NEAR(66.0, link_rect.left, 0.001);
906 EXPECT_NEAR(544.0, link_rect.top, 0.001);
907 EXPECT_NEAR(196.0, link_rect.right, 0.001);
908 EXPECT_NEAR(529.0, link_rect.bottom, 0.001);
909 }
else if (start_pos == 4) {
911 EXPECT_EQ(1, quad_point_count);
912 FS_QUADPOINTSF quad_points;
914 EXPECT_NEAR(83.0, quad_points.x1, 0.001);
915 EXPECT_NEAR(453.0, quad_points.y1, 0.001);
916 EXPECT_NEAR(178.0, quad_points.x2, 0.001);
917 EXPECT_NEAR(453.0, quad_points.y2, 0.001);
918 EXPECT_NEAR(83.0, quad_points.x3, 0.001);
919 EXPECT_NEAR(440.0, quad_points.y3, 0.001);
920 EXPECT_NEAR(178.0, quad_points.x4, 0.001);
921 EXPECT_NEAR(440.0, quad_points.y4, 0.001);
925 EXPECT_NEAR(link_rect.left, quad_points.x1, 0.001);
926 EXPECT_NEAR(link_rect.top, quad_points.y1, 0.001);
927 EXPECT_NEAR(link_rect.right, quad_points.x4, 0.001);
928 EXPECT_NEAR(link_rect.bottom, quad_points.y4, 0.001);
932 EXPECT_EQ(annot_subtype_link_count, link_count);
938 ASSERT_TRUE(OpenDocument(
"hello_world.pdf"));
939 FPDF_PAGE page = LoadPage(0);
943 ASSERT_TRUE(textpage);
945 constexpr auto kExpectedFontsSizes =
fxcrt::ToArray<
const double>(
946 {12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 1, 1,
947 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16});
950 ASSERT_EQ(
std::size(kExpectedFontsSizes),
static_cast<size_t>(count));
951 for (
int i = 0; i < count; ++i) {
959 ASSERT_TRUE(OpenDocument(
"hello_world.pdf"));
960 FPDF_PAGE page = LoadPage(0);
964 ASSERT_TRUE(textpage);
965 std::vector<
char> font_name;
966 size_t num_chars1 = strlen(
"Hello, world!");
967 const char kExpectedFontName1[] =
"Times-Roman";
969 for (size_t i = 0; i < num_chars1; i++) {
971 unsigned long length =
972 FPDFText_GetFontInfo(textpage, i,
nullptr, 0, &flags);
973 static constexpr unsigned long expected_length =
sizeof(kExpectedFontName1);
974 ASSERT_EQ(expected_length, length);
976 font_name.resize(length);
977 std::fill(font_name.begin(), font_name.end(),
'a');
979 EXPECT_EQ(expected_length,
980 FPDFText_GetFontInfo(textpage, i, font_name.data(),
981 font_name.size(), &flags));
982 EXPECT_STREQ(kExpectedFontName1, font_name.data());
987 font_name.pop_back();
988 std::fill(font_name.begin(), font_name.end(),
'a');
989 EXPECT_EQ(
sizeof(kExpectedFontName1),
990 FPDFText_GetFontInfo(textpage, 0, font_name.data(),
991 font_name.size(),
nullptr));
992 for (
char a : font_name)
997 EXPECT_EQ(0u, FPDFText_GetFontInfo(textpage, num_chars1, font_name.data(),
998 font_name.size(),
nullptr));
999 EXPECT_EQ(0u, FPDFText_GetFontInfo(textpage, num_chars1 + 1, font_name.data(),
1000 font_name.size(),
nullptr));
1002 size_t num_chars2 = strlen(
"Goodbye, world!");
1003 const char kExpectedFontName2[] =
"Helvetica";
1004 for (size_t i = num_chars1 + 2; i < num_chars1 + num_chars2 + 2; i++) {
1006 unsigned long length =
1007 FPDFText_GetFontInfo(textpage, i,
nullptr, 0, &flags);
1008 static constexpr unsigned long expected_length =
sizeof(kExpectedFontName2);
1009 ASSERT_EQ(expected_length, length);
1011 font_name.resize(length);
1012 std::fill(font_name.begin(), font_name.end(),
'a');
1014 EXPECT_EQ(expected_length,
1015 FPDFText_GetFontInfo(textpage, i, font_name.data(),
1016 font_name.size(), &flags));
1017 EXPECT_STREQ(kExpectedFontName2, font_name.data());
1024 EXPECT_EQ(0u, FPDFText_GetFontInfo(
nullptr, 0, font_name.data(),
1025 font_name.size(),
nullptr));
1027 EXPECT_EQ(
sizeof(kExpectedFontName1),
1030 EXPECT_EQ(0u, FPDFText_GetFontInfo(textpage, -1, font_name.data(),
1031 font_name.size(),
nullptr));
1033 EXPECT_EQ(0u, FPDFText_GetFontInfo(textpage, 1000, font_name.data(),
1034 font_name.size(),
nullptr));
1041 ASSERT_TRUE(OpenDocument(
"bug_583.pdf"));
1042 FPDF_PAGE page = LoadPage(0);
1046 ASSERT_TRUE(textpage);
1056 ASSERT_TRUE(OpenDocument(
"hello_world.pdf"));
1057 ScopedEmbedderTestPage page = LoadScopedPage(0);
1060 ScopedFPDFTextPage textpage(FPDFText_LoadPage(page.get()));
1061 ASSERT_TRUE(textpage);
1063 EXPECT_EQ(
static_cast<
unsigned int>(
'H'),
1064 FPDFText_GetUnicode(textpage.get(), 0));
1065 EXPECT_EQ(0, FPDFText_IsGenerated(textpage.get(), 0));
1066 EXPECT_EQ(
static_cast<
unsigned int>(
' '),
1067 FPDFText_GetUnicode(textpage.get(), 6));
1068 EXPECT_EQ(0, FPDFText_IsGenerated(textpage.get(), 6));
1070 EXPECT_EQ(
static_cast<
unsigned int>(
'\r'),
1071 FPDFText_GetUnicode(textpage.get(), 13));
1072 EXPECT_EQ(1, FPDFText_IsGenerated(textpage.get(), 13));
1073 EXPECT_EQ(
static_cast<
unsigned int>(
'\n'),
1074 FPDFText_GetUnicode(textpage.get(), 14));
1075 EXPECT_EQ(1, FPDFText_IsGenerated(textpage.get(), 14));
1077 EXPECT_EQ(-1, FPDFText_IsGenerated(textpage.get(), -1));
1078 EXPECT_EQ(-1, FPDFText_IsGenerated(textpage.get(), kHelloGoodbyeTextSize));
1083 ASSERT_TRUE(OpenDocument(
"bug_781804.pdf"));
1084 ScopedEmbedderTestPage page = LoadScopedPage(0);
1087 ScopedFPDFTextPage textpage(FPDFText_LoadPage(page.get()));
1088 ASSERT_TRUE(textpage);
1090 EXPECT_EQ(
static_cast<
unsigned int>(
'V'),
1091 FPDFText_GetUnicode(textpage.get(), 0));
1092 EXPECT_EQ(0, FPDFText_IsHyphen(textpage.get(), 0));
1093 EXPECT_EQ(
static_cast<
unsigned int>(
'\2'),
1094 FPDFText_GetUnicode(textpage.get(), 6));
1095 EXPECT_EQ(1, FPDFText_IsHyphen(textpage.get(), 6));
1097 EXPECT_EQ(
static_cast<
unsigned int>(
'U'),
1098 FPDFText_GetUnicode(textpage.get(), 14));
1099 EXPECT_EQ(0, FPDFText_IsHyphen(textpage.get(), 14));
1100 EXPECT_EQ(
static_cast<
unsigned int>(L'\u2010'),
1101 FPDFText_GetUnicode(textpage.get(), 18));
1102 EXPECT_EQ(0, FPDFText_IsHyphen(textpage.get(), 18));
1104 EXPECT_EQ(-1, FPDFText_IsHyphen(textpage.get(), -1));
1105 EXPECT_EQ(-1, FPDFText_IsHyphen(textpage.get(), 1000));
1110 ASSERT_TRUE(OpenDocument(
"bug_1388_2.pdf"));
1111 ScopedEmbedderTestPage page = LoadScopedPage(0);
1114 constexpr int kExpectedCharCount = 5;
1115 ScopedFPDFTextPage textpage(FPDFText_LoadPage(page.get()));
1116 ASSERT_TRUE(textpage);
1117 EXPECT_EQ(kExpectedCharCount, FPDFText_CountChars(textpage.get()));
1119 EXPECT_EQ(
static_cast<
unsigned int>(
'X'),
1120 FPDFText_GetUnicode(textpage.get(), 0));
1121 EXPECT_EQ(0, FPDFText_HasUnicodeMapError(textpage.get(), 0));
1122 EXPECT_EQ(
static_cast<
unsigned int>(
' '),
1123 FPDFText_GetUnicode(textpage.get(), 1));
1124 EXPECT_EQ(0, FPDFText_HasUnicodeMapError(textpage.get(), 1));
1126 EXPECT_EQ(31u, FPDFText_GetUnicode(textpage.get(), 2));
1127 EXPECT_EQ(1, FPDFText_HasUnicodeMapError(textpage.get(), 2));
1129 EXPECT_EQ(-1, FPDFText_HasUnicodeMapError(textpage.get(), -1));
1131 FPDFText_HasUnicodeMapError(textpage.get(), kExpectedCharCount));
1136 ASSERT_TRUE(OpenDocument(
"bug_921.pdf"));
1137 FPDF_PAGE page = LoadPage(0);
1141 ASSERT_TRUE(textpage);
1143 static constexpr auto kData =
fxcrt::ToArray<
const unsigned int>(
1144 {1095, 1077, 1083, 1086, 1074, 1077, 1095, 1077, 1089, 1082, 1086, 1077,
1145 32, 1089, 1090, 1088, 1072, 1076, 1072, 1085, 1080, 1077, 46, 32});
1146 static constexpr int kStartIndex = 238;
1149 for (size_t i = 0; i <
std::size(kData); ++i) {
1150 EXPECT_EQ(kData[i], FPDFText_GetUnicode(textpage, kStartIndex + i));
1152 std::array<
unsigned short,
std::size(kData) + 1> buffer;
1153 fxcrt::Fill(buffer, 0xbdbd);
1155 FPDFText_GetText(textpage, kStartIndex, kData.size(), buffer.data());
1156 ASSERT_GT(count, 0);
1157 ASSERT_EQ(
std::size(kData) + 1,
static_cast<size_t>(count));
1158 for (size_t i = 0; i <
std::size(kData); ++i) {
1159 EXPECT_EQ(kData[i], buffer[i]);
1161 EXPECT_EQ(0, buffer[kData.size()]);
1168 ASSERT_TRUE(OpenDocument(
"bug_781804.pdf"));
1169 FPDF_PAGE page = LoadPage(0);
1173 ASSERT_TRUE(textpage);
1179 constexpr auto soft_expected =
fxcrt::ToArray<
unsigned short>(
1180 {0x0056, 0x0065, 0x0072, 0x0069, 0x0074, 0x0061, 0xfffe, 0x0073, 0x0065,
1181 0x0072, 0x0075, 0x006D, 0x0000});
1183 constexpr int count =
std::size(soft_expected) - 1;
1184 std::array<
unsigned short, soft_expected.size()> buffer = {};
1185 EXPECT_EQ(count + 1, FPDFText_GetText(textpage, 0, count, buffer.data()));
1186 EXPECT_THAT(buffer, ElementsAreArray(soft_expected));
1193 constexpr size_t offset =
std::size(soft_expected) + 1;
1196 constexpr auto hard_expected =
fxcrt::ToArray<
unsigned short>(
1197 {0x0055, 0x0073, 0x0065, 0x0072, 0x2010, 0x000d, 0x000a, 0x0067, 0x0065,
1198 0x006e, 0x0065, 0x0072, 0x0061, 0x0074, 0x0065, 0x0064, 0x0000});
1199 constexpr int count =
std::size(hard_expected) - 1;
1200 std::array<
unsigned short, hard_expected.size()> buffer;
1201 EXPECT_EQ(count + 1,
1202 FPDFText_GetText(textpage, offset, count, buffer.data()));
1203 for (
int i = 0; i < count; i++) {
1204 EXPECT_EQ(hard_expected[i], buffer[i]);
1214 ASSERT_TRUE(OpenDocument(
"bug_782596.pdf"));
1215 FPDF_PAGE page = LoadPage(0);
1218 ASSERT_TRUE(textpage);
1224 ASSERT_TRUE(OpenDocument(
"control_characters.pdf"));
1225 FPDF_PAGE page = LoadPage(0);
1229 ASSERT_TRUE(textpage);
1232 unsigned short buffer[128];
1233 fxcrt::Fill(buffer, 0xbdbd);
1235 ASSERT_EQ(kHelloGoodbyeTextSize, num_chars);
1237 check_unsigned_shorts(kHelloGoodbyeText, buffer, kHelloGoodbyeTextSize));
1240 static const char expected_substring[] =
"Goodbye, world!";
1243 static const int offset = 17;
1244 fxcrt::Fill(buffer, 0xbdbd);
1247 ASSERT_GE(num_chars, 0);
1248 EXPECT_EQ(
sizeof(expected_substring),
static_cast<size_t>(num_chars));
1249 EXPECT_TRUE(check_unsigned_shorts(expected_substring, buffer,
1250 sizeof(expected_substring)));
1259 ASSERT_TRUE(OpenDocument(
"bug_1029.pdf"));
1260 FPDF_PAGE page = LoadPage(0);
1264 ASSERT_TRUE(textpage);
1266 constexpr int page_range_offset = 171;
1267 constexpr int page_range_length = 56;
1275 static constexpr auto expected =
fxcrt::ToArray<
unsigned int>({
1276 0x004d, 0x0045, 0x0054, 0x0041, 0x0044, 0x0041, 0x0054, 0x0041,
1277 0x0020, 0x0074, 0x0061, 0x0062, 0x006c, 0x0065, 0x002e, 0x0020,
1278 0x0057, 0x0068, 0x0065, 0x006e, 0x0020, 0x0074, 0x0068, 0x0065,
1279 0x0020, 0x0073, 0x0070, 0x006c, 0x0069, 0x0074, 0x0020, 0x0068,
1280 0x0061, 0x0073, 0x0020, 0x0063, 0x006f, 0x006d, 0x006d, 0x0069,
1281 0x0074, 0x0074, 0x0065, 0x0064, 0x002c, 0x0020, 0x0069, 0x0074,
1282 0x0020, 0x006e, 0x006f, 0x0074, 0x0069, 0x0002, 0x0066, 0x0069,
1284 static_assert(page_range_length ==
std::size(expected),
1285 "Expected should be the same size as the range being "
1286 "extracted from page.");
1287 EXPECT_LT(page_range_offset + page_range_length,
1290 for (
int i = 0; i < page_range_length; ++i) {
1291 EXPECT_EQ(expected[i],
1300 ASSERT_TRUE(OpenDocument(
"hello_world.pdf"));
1301 FPDF_PAGE page = LoadPage(0);
1305 ASSERT_TRUE(textpage);
1310 unsigned short buffer[128];
1312 ASSERT_EQ(kHelloGoodbyeTextSize, num_chars);
1313 EXPECT_TRUE(check_unsigned_shorts(kHelloGoodbyeText, buffer,
1314 kHelloGoodbyeTextSize));
1318 static const int kHelloWorldEnd = strlen(
"Hello, world!");
1319 static const int kGoodbyeWorldStart = kHelloWorldEnd + 2;
1320 for (
int start = 0; start < kHelloWorldEnd; ++start) {
1333 int expected_value = start ? 2 : 1;
1334 EXPECT_EQ(expected_value,
1343 for (
int start = 0; start < kHelloWorldEnd; ++start) {
1349 const int kExpectedLength = strlen(kHelloGoodbyeText);
1350 for (
int start = kGoodbyeWorldStart + 1; start < kExpectedLength; ++start) {
1359 for (
int start = kExpectedLength; start < 100; ++start) {
1372 ASSERT_TRUE(OpenDocument(
"hello_world.pdf"));
1373 FPDF_PAGE page = LoadPage(0);
1377 ASSERT_TRUE(text_page);
1381 ASSERT_TRUE(text_object);
1384 constexpr char kHelloText[] =
"Hello, world!";
1386 constexpr unsigned long kHelloUTF16Size =
std::size(kHelloText) * 2;
1387 constexpr wchar_t kHelloWideText[] = L"Hello, world!";
1389 ASSERT_EQ(kHelloUTF16Size, size);
1391 std::vector<
unsigned short> buffer(size);
1393 FPDFTextObj_GetText(text_object, text_page, buffer.data(), size));
1394 ASSERT_EQ(kHelloWideText, GetPlatformWString(buffer.data()));
1406 FPDFTextObj_GetText(text_object, text_page, buffer.data(), buffer.size());
1407 ASSERT_EQ(kHelloUTF16Size, size);
1408 ASSERT_EQ(
'x', buffer[0]);
1409 ASSERT_EQ(
'\0', buffer[1]);
1416 static constexpr int kPageCount = 4;
1417 static constexpr std::array<FS_RECTF, kPageCount> kBoxes = {{
1418 {50.0f, 150.0f, 150.0f, 50.0f},
1419 {50.0f, 150.0f, 150.0f, 50.0f},
1420 {60.0f, 150.0f, 150.0f, 60.0f},
1421 {60.0f, 150.0f, 150.0f, 60.0f},
1423 static constexpr std::array<
const char*, kPageCount> kExpectedText = {{
1424 " world!\r\ndbye, world!",
1425 " world!\r\ndbye, world!",
1430 ASSERT_TRUE(OpenDocument(
"cropped_text.pdf"));
1431 ASSERT_EQ(kPageCount, FPDF_GetPageCount(document()));
1433 for (
int i = 0; i < kPageCount; ++i) {
1434 ScopedEmbedderTestPage page = LoadScopedPage(i);
1438 EXPECT_TRUE(FPDF_GetPageBoundingBox(page.get(), &box));
1439 EXPECT_EQ(kBoxes[i].left, box.left);
1440 EXPECT_EQ(kBoxes[i].top, box.top);
1441 EXPECT_EQ(kBoxes[i].right, box.right);
1442 EXPECT_EQ(kBoxes[i].bottom, box.bottom);
1444 ScopedFPDFTextPage textpage(FPDFText_LoadPage(page.get()));
1445 ASSERT_TRUE(textpage);
1447 unsigned short buffer[128];
1448 fxcrt::Fill(buffer, 0xbdbd);
1449 int num_chars = FPDFText_GetText(textpage.get(), 0, 128, buffer);
1450 ASSERT_EQ(kHelloGoodbyeTextSize, num_chars);
1451 EXPECT_TRUE(check_unsigned_shorts(kHelloGoodbyeText, buffer,
1452 kHelloGoodbyeTextSize));
1454 int expected_char_count = strlen(kExpectedText[i]);
1455 ASSERT_EQ(expected_char_count,
1456 FPDFText_GetBoundedText(textpage.get(), box.left, box.top,
1457 box.right, box.bottom,
nullptr, 0));
1459 fxcrt::Fill(buffer, 0xbdbd);
1460 ASSERT_EQ(expected_char_count + 1,
1461 FPDFText_GetBoundedText(textpage.get(), box.left, box.top,
1462 box.right, box.bottom, buffer, 128));
1464 check_unsigned_shorts(kExpectedText[i], buffer, expected_char_count));
1469 ASSERT_TRUE(OpenDocument(
"bug_1139.pdf"));
1470 FPDF_PAGE page = LoadPage(0);
1474 ASSERT_TRUE(text_page);
1482 unsigned short buffer[128];
1484 ASSERT_EQ(kHelloGoodbyeTextSize, num_chars);
1486 check_unsigned_shorts(kHelloGoodbyeText, buffer, kHelloGoodbyeTextSize));
1492 ASSERT_TRUE(OpenDocument(
"bug_642.pdf"));
1493 ScopedEmbedderTestPage page = LoadScopedPage(0);
1496 ScopedFPDFTextPage text_page(FPDFText_LoadPage(page.get()));
1497 ASSERT_TRUE(text_page);
1499 constexpr char kText[] =
"ABCD";
1500 constexpr size_t kTextSize =
std::size(kText);
1502 EXPECT_EQ(
static_cast<
int>(kTextSize) - 1,
1503 FPDFText_CountChars(text_page.get()));
1505 unsigned short buffer[kTextSize];
1507 FPDFText_GetText(text_page.get(), 0,
std::size(buffer) - 1, buffer);
1508 ASSERT_EQ(
static_cast<
int>(kTextSize), num_chars);
1509 EXPECT_TRUE(check_unsigned_shorts(kText, buffer, kTextSize));
1513 ASSERT_TRUE(OpenDocument(
"rotated_text.pdf"));
1514 FPDF_PAGE page = LoadPage(0);
1518 ASSERT_TRUE(text_page);
1520 static constexpr int kSubstringsSize[] = {
1521 std::size(
"Hello,"),
std::size(
" world!\r\n"),
std::size(
"Goodbye,")};
1529 EXPECT_FLOAT_EQ(-1.0f,
1535 FPDFText_GetCharAngle(text_page, kSubstringsSize[0]), 0.001);
1538 FPDFText_GetCharAngle(text_page, kSubstringsSize[0] + kSubstringsSize[1]),
1542 FPDFText_GetCharAngle(text_page, kSubstringsSize[0] + kSubstringsSize[1] +
1543 kSubstringsSize[2]),
1551 ASSERT_TRUE(OpenDocument(
"font_weight.pdf"));
1552 FPDF_PAGE page = LoadPage(0);
1556 ASSERT_TRUE(text_page);
1578 ASSERT_TRUE(OpenDocument(
"text_render_mode.pdf"));
1579 ScopedEmbedderTestPage page = LoadScopedPage(0);
1582 ScopedFPDFTextPage text_page(FPDFText_LoadPage(page.get()));
1583 ASSERT_TRUE(text_page);
1585 ASSERT_EQ(12, FPDFText_CountChars(text_page.get()));
1588 ASSERT_FALSE(FPDFText_GetTextObject(text_page.get(), -1));
1589 ASSERT_FALSE(FPDFText_GetTextObject(text_page.get(), 314));
1591 FPDF_PAGEOBJECT text_object = FPDFText_GetTextObject(text_page.get(), 0);
1592 ASSERT_TRUE(text_object);
1594 EXPECT_EQ(FPDF_TEXTRENDERMODE_FILL,
1597 text_object = FPDFText_GetTextObject(text_page.get(), 7);
1598 ASSERT_TRUE(text_object);
1600 EXPECT_EQ(FPDF_TEXTRENDERMODE_STROKE,
1605 ASSERT_TRUE(OpenDocument(
"text_color.pdf"));
1606 FPDF_PAGE page = LoadPage(0);
1610 ASSERT_TRUE(text_page);
1628 ASSERT_EQ(0xffu, r);
1631 ASSERT_EQ(0xffu, a);
1638 ASSERT_TRUE(OpenDocument(
"text_color.pdf"));
1639 FPDF_PAGE page = LoadPage(0);
1643 ASSERT_TRUE(text_page);
1662 ASSERT_EQ(0xffu, g);
1664 ASSERT_EQ(0xffu, a);
1671 constexpr char kExpectedText[] =
"A1\r\nA2\r\nA3";
1672 constexpr size_t kExpectedTextSize =
std::size(kExpectedText);
1673 constexpr auto kExpectedMatrices =
fxcrt::ToArray<
const FS_MATRIX>({
1674 {12.0f, 0.0f, 0.0f, 10.0f, 66.0f, 90.0f},
1675 {12.0f, 0.0f, 0.0f, 10.0f, 66.0f, 90.0f},
1676 {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
1677 {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
1678 {12.0f, 0.0f, 0.0f, 10.0f, 38.0f, 60.0f},
1679 {12.0f, 0.0f, 0.0f, 10.0f, 38.0f, 60.0f},
1680 {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
1681 {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
1682 {1.0f, 0.0f, 0.0f, 0.833333, 60.0f, 130.0f},
1683 {1.0f, 0.0f, 0.0f, 0.833333, 60.0f, 130.0f},
1685 constexpr size_t kExpectedCount =
std::size(kExpectedMatrices);
1686 static_assert(kExpectedCount + 1 == kExpectedTextSize,
1687 "Bad expected matrix size");
1689 ASSERT_TRUE(OpenDocument(
"font_matrix.pdf"));
1690 ScopedEmbedderTestPage page = LoadScopedPage(0);
1693 ScopedFPDFTextPage text_page(FPDFText_LoadPage(page.get()));
1694 ASSERT_TRUE(text_page);
1695 ASSERT_EQ(
static_cast<
int>(kExpectedCount),
1696 FPDFText_CountChars(text_page.get()));
1700 unsigned short buffer[kExpectedTextSize];
1701 ASSERT_EQ(
static_cast<
int>(kExpectedTextSize),
1702 FPDFText_GetText(text_page.get(), 0, kExpectedCount, buffer));
1704 check_unsigned_shorts(kExpectedText, buffer, kExpectedTextSize));
1709 for (size_t i = 0; i < kExpectedCount; ++i) {
1710 ASSERT_TRUE(FPDFText_GetMatrix(text_page.get(), i, &matrix)) << i;
1711 EXPECT_FLOAT_EQ(kExpectedMatrices[i].a, matrix.a) << i;
1712 EXPECT_FLOAT_EQ(kExpectedMatrices[i].b, matrix.b) << i;
1713 EXPECT_FLOAT_EQ(kExpectedMatrices[i].c, matrix.c) << i;
1714 EXPECT_FLOAT_EQ(kExpectedMatrices[i].d, matrix.d) << i;
1715 EXPECT_FLOAT_EQ(kExpectedMatrices[i].e, matrix.e) << i;
1716 EXPECT_FLOAT_EQ(kExpectedMatrices[i].f, matrix.f) << i;
1721 EXPECT_FALSE(FPDFText_GetMatrix(text_page.get(), 10, &matrix));
1722 EXPECT_FALSE(FPDFText_GetMatrix(text_page.get(), -1, &matrix));
1723 EXPECT_FALSE(FPDFText_GetMatrix(text_page.get(), 0,
nullptr));
1728 constexpr double kExpectedCharWidth = 8.460;
1729 constexpr double kExpectedCharHeight = 6.600;
1730 constexpr float kExpectedLooseCharWidth = 8.664f;
1731 constexpr float kExpectedLooseCharHeight = 12.0f;
1733 ASSERT_TRUE(OpenDocument(
"font_matrix.pdf"));
1734 ScopedEmbedderTestPage page = LoadScopedPage(0);
1737 ScopedFPDFTextPage text_page(FPDFText_LoadPage(page.get()));
1738 ASSERT_TRUE(text_page);
1746 FPDFText_GetCharBox(text_page.get(), 0, &left, &right, &bottom, &top));
1747 EXPECT_NEAR(kExpectedCharWidth, right - left, 0.001);
1748 EXPECT_NEAR(kExpectedCharHeight, top - bottom, 0.001);
1750 FPDFText_GetCharBox(text_page.get(), 4, &left, &right, &bottom, &top));
1751 EXPECT_NEAR(kExpectedCharWidth, right - left, 0.001);
1752 EXPECT_NEAR(kExpectedCharHeight, top - bottom, 0.001);
1754 FPDFText_GetCharBox(text_page.get(), 8, &left, &right, &bottom, &top));
1755 EXPECT_NEAR(kExpectedCharWidth, right - left, 0.001);
1756 EXPECT_NEAR(kExpectedCharHeight, top - bottom, 0.001);
1760 ASSERT_TRUE(FPDFText_GetLooseCharBox(text_page.get(), 0, &rect));
1761 EXPECT_FLOAT_EQ(kExpectedLooseCharWidth, rect.right - rect.left);
1762 EXPECT_FLOAT_EQ(kExpectedLooseCharHeight, rect.top - rect.bottom);
1763 ASSERT_TRUE(FPDFText_GetLooseCharBox(text_page.get(), 4, &rect));
1764 EXPECT_FLOAT_EQ(kExpectedLooseCharWidth, rect.right - rect.left);
1765 EXPECT_FLOAT_EQ(kExpectedLooseCharHeight, rect.top - rect.bottom);
1766 ASSERT_TRUE(FPDFText_GetLooseCharBox(text_page.get(), 8, &rect));
1767 EXPECT_FLOAT_EQ(kExpectedLooseCharWidth, rect.right - rect.left);
1768 EXPECT_NEAR(kExpectedLooseCharHeight, rect.top - rect.bottom, 0.00001);
1772 ASSERT_TRUE(OpenDocument(
"bug_1591.pdf"));
1773 ScopedEmbedderTestPage page = LoadScopedPage(0);
1776 ScopedFPDFTextPage text_page(FPDFText_LoadPage(page.get()));
1777 ASSERT_TRUE(text_page);
1778 ASSERT_EQ(5, FPDFText_CountChars(text_page.get()));
1780 EXPECT_EQ(49u, FPDFText_GetUnicode(text_page.get(), 0));
1781 EXPECT_EQ(32u, FPDFText_GetUnicode(text_page.get(), 1));
1782 EXPECT_EQ(50u, FPDFText_GetUnicode(text_page.get(), 2));
1783 EXPECT_EQ(32u, FPDFText_GetUnicode(text_page.get(), 3));
1784 EXPECT_EQ(49u, FPDFText_GetUnicode(text_page.get(), 4));
1792 FPDFText_GetCharBox(text_page.get(), 0, &left, &right, &bottom, &top));
1793 EXPECT_DOUBLE_EQ(63.439998626708984, left);
1794 EXPECT_DOUBLE_EQ(65.360000610351562, right);
1795 EXPECT_DOUBLE_EQ(50.0, bottom);
1796 EXPECT_DOUBLE_EQ(61.520000457763672, top);
1798 FPDFText_GetCharBox(text_page.get(), 1, &left, &right, &bottom, &top));
1799 EXPECT_DOUBLE_EQ(62.007999420166016, left);
1800 EXPECT_DOUBLE_EQ(62.007999420166016, right);
1801 EXPECT_DOUBLE_EQ(50.0, bottom);
1802 EXPECT_DOUBLE_EQ(50.0, top);
1804 FPDFText_GetCharBox(text_page.get(), 2, &left, &right, &bottom, &top));
1805 EXPECT_DOUBLE_EQ(86.0, left);
1806 EXPECT_DOUBLE_EQ(88.400001525878906, right);
1807 EXPECT_DOUBLE_EQ(50.0, bottom);
1808 EXPECT_DOUBLE_EQ(50.240001678466797, top);
1810 FPDFText_GetCharBox(text_page.get(), 3, &left, &right, &bottom, &top));
1811 EXPECT_DOUBLE_EQ(86.010002136230469, left);
1812 EXPECT_DOUBLE_EQ(86.010002136230469, right);
1813 EXPECT_DOUBLE_EQ(50.0, bottom);
1814 EXPECT_DOUBLE_EQ(50.0, top);
1816 FPDFText_GetCharBox(text_page.get(), 4, &left, &right, &bottom, &top));
1817 EXPECT_DOUBLE_EQ(99.44000244140625, left);
1818 EXPECT_DOUBLE_EQ(101.36000061035156, right);
1819 EXPECT_DOUBLE_EQ(50.0, bottom);
1820 EXPECT_DOUBLE_EQ(61.520000457763672, top);
1824 constexpr char kExpectedText[] =
1825 "{fay,jeff,sanjay,wilsonh,kerr,m3b,tushar,\x02k es,gruber}@google.com";
1826 constexpr int kExpectedTextCount =
std::size(kExpectedText) - 1;
1828 ASSERT_TRUE(OpenDocument(
"bigtable_mini.pdf"));
1829 ScopedEmbedderTestPage page = LoadScopedPage(0);
1832 ScopedFPDFTextPage text_page(FPDFText_LoadPage(page.get()));
1833 ASSERT_TRUE(text_page);
1834 int char_count = FPDFText_CountChars(text_page.get());
1835 ASSERT_GE(char_count, 0);
1836 ASSERT_EQ(kExpectedTextCount, char_count);
1838 for (
int i = 0; i < kExpectedTextCount; ++i) {
1839 EXPECT_EQ(
static_cast<uint32_t>(
UNSAFE_TODO(kExpectedText[i])),
1840 FPDFText_GetUnicode(text_page.get(), i));
1845 ASSERT_TRUE(OpenDocument(
"bug_1769.pdf"));
1846 ScopedEmbedderTestPage page = LoadScopedPage(0);
1849 ScopedFPDFTextPage textpage(FPDFText_LoadPage(page.get()));
1850 ASSERT_TRUE(textpage);
1852 unsigned short buffer[128] = {};
1857 ASSERT_EQ(10, FPDFText_GetText(textpage.get(), 0, 128, buffer));
1858 EXPECT_TRUE(check_unsigned_shorts(
"wo d wo d", buffer, 10));
FPDF_EXPORT int FPDF_CALLCONV FPDFPage_GetAnnotCount(FPDF_PAGE page)
FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV FPDFPage_GetAnnot(FPDF_PAGE page, int index)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFLink_GetAnnotRect(FPDF_LINK link_annot, FS_RECTF *rect)
FPDF_EXPORT int FPDF_CALLCONV FPDFLink_CountQuadPoints(FPDF_LINK link_annot)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFLink_GetQuadPoints(FPDF_LINK link_annot, int quad_index, FS_QUADPOINTSF *quad_points)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFLink_Enumerate(FPDF_PAGE page, int *start_pos, FPDF_LINK *link_annot)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFTextObj_GetText(FPDF_PAGEOBJECT text_object, FPDF_TEXTPAGE text_page, FPDF_WCHAR *buffer, unsigned long length)
FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV FPDFPage_GetObject(FPDF_PAGE page, int index)
FPDF_EXPORT FPDF_TEXT_RENDERMODE FPDF_CALLCONV FPDFTextObj_GetTextRenderMode(FPDF_PAGEOBJECT text)
FPDF_EXPORT int FPDF_CALLCONV FPDFPageObj_GetType(FPDF_PAGEOBJECT page_object)
#define FPDF_PAGEOBJ_TEXT
FPDF_EXPORT int FPDF_CALLCONV FPDFPage_CountObjects(FPDF_PAGE page)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFText_GetStrokeColor(FPDF_TEXTPAGE text_page, int index, unsigned int *R, unsigned int *G, unsigned int *B, unsigned int *A)
FPDF_EXPORT int FPDF_CALLCONV FPDFLink_GetURL(FPDF_PAGELINK link_page, int link_index, unsigned short *buffer, int buflen)
FPDF_EXPORT int FPDF_CALLCONV FPDFText_GetText(FPDF_TEXTPAGE page, int start_index, int char_count, unsigned short *result)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFLink_GetTextRange(FPDF_PAGELINK link_page, int link_index, int *start_char_index, int *char_count)
FPDF_EXPORT int FPDF_CALLCONV FPDFText_IsGenerated(FPDF_TEXTPAGE text_page, int index)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFText_GetCharOrigin(FPDF_TEXTPAGE text_page, int index, double *x, double *y)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFText_GetFillColor(FPDF_TEXTPAGE text_page, int index, unsigned int *R, unsigned int *G, unsigned int *B, unsigned int *A)
FPDF_EXPORT int FPDF_CALLCONV FPDFText_IsHyphen(FPDF_TEXTPAGE text_page, int index)
FPDF_EXPORT int FPDF_CALLCONV FPDFText_GetCharIndexAtPos(FPDF_TEXTPAGE text_page, double x, double y, double xTolerance, double yTolerance)
FPDF_EXPORT void FPDF_CALLCONV FPDFLink_CloseWebLinks(FPDF_PAGELINK link_page)
FPDF_EXPORT float FPDF_CALLCONV FPDFText_GetCharAngle(FPDF_TEXTPAGE text_page, int index)
FPDF_EXPORT int FPDF_CALLCONV FPDFText_HasUnicodeMapError(FPDF_TEXTPAGE text_page, int index)
FPDF_EXPORT int FPDF_CALLCONV FPDFText_GetBoundedText(FPDF_TEXTPAGE text_page, double left, double top, double right, double bottom, unsigned short *buffer, int buflen)
FPDF_EXPORT int FPDF_CALLCONV FPDFLink_CountRects(FPDF_PAGELINK link_page, int link_index)
FPDF_EXPORT int FPDF_CALLCONV FPDFText_GetFontWeight(FPDF_TEXTPAGE text_page, int index)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFText_GetLooseCharBox(FPDF_TEXTPAGE text_page, int index, FS_RECTF *rect)
FPDF_EXPORT double FPDF_CALLCONV FPDFText_GetFontSize(FPDF_TEXTPAGE text_page, int index)
FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV FPDFText_GetTextObject(FPDF_TEXTPAGE text_page, int index)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFText_GetCharBox(FPDF_TEXTPAGE text_page, int index, double *left, double *right, double *bottom, double *top)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFLink_GetRect(FPDF_PAGELINK link_page, int link_index, int rect_index, double *left, double *top, double *right, double *bottom)
FPDF_EXPORT int FPDF_CALLCONV FPDFText_CountRects(FPDF_TEXTPAGE text_page, int start, int count)
FPDF_EXPORT int FPDF_CALLCONV FPDFText_CountChars(FPDF_TEXTPAGE text_page)
FPDF_EXPORT FPDF_TEXTPAGE FPDF_CALLCONV FPDFText_LoadPage(FPDF_PAGE page)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFText_GetMatrix(FPDF_TEXTPAGE text_page, int index, FS_MATRIX *matrix)
FPDF_EXPORT void FPDF_CALLCONV FPDFText_ClosePage(FPDF_TEXTPAGE text_page)
FPDF_EXPORT FPDF_PAGELINK FPDF_CALLCONV FPDFLink_LoadWebLinks(FPDF_TEXTPAGE text_page)
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFText_GetFontInfo(FPDF_TEXTPAGE text_page, int index, void *buffer, unsigned long buflen, int *flags)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFText_GetRect(FPDF_TEXTPAGE text_page, int rect_index, double *left, double *top, double *right, double *bottom)
FPDF_EXPORT unsigned int FPDF_CALLCONV FPDFText_GetUnicode(FPDF_TEXTPAGE text_page, int index)
FPDF_EXPORT int FPDF_CALLCONV FPDFLink_CountWebLinks(FPDF_PAGELINK link_page)
#define FPDF_MATCHWHOLEWORD
#define MAYBE_TextSearchLatinExtended
TEST_F(FPDFTextEmbedderTest, Text)
#define FXFONT_NONSYMBOLIC
std::unique_ptr< FPDF_WCHAR, pdfium::FreeDeleter > ScopedFPDFWideString