OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "pdf/pdfium/pdfium_engine.h" | 5 #include "pdf/pdfium/pdfium_engine.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
11 #include <algorithm> | 11 #include <algorithm> |
12 #include <memory> | 12 #include <memory> |
13 #include <set> | 13 #include <set> |
14 | 14 |
15 #include "base/i18n/encoding_detection.h" | 15 #include "base/i18n/encoding_detection.h" |
16 #include "base/i18n/icu_string_conversions.h" | 16 #include "base/i18n/icu_string_conversions.h" |
17 #include "base/lazy_instance.h" | 17 #include "base/lazy_instance.h" |
18 #include "base/logging.h" | 18 #include "base/logging.h" |
19 #include "base/macros.h" | 19 #include "base/macros.h" |
| 20 #include "base/memory/ptr_util.h" |
20 #include "base/numerics/safe_conversions.h" | 21 #include "base/numerics/safe_conversions.h" |
21 #include "base/stl_util.h" | 22 #include "base/stl_util.h" |
22 #include "base/strings/string_number_conversions.h" | 23 #include "base/strings/string_number_conversions.h" |
23 #include "base/strings/string_piece.h" | 24 #include "base/strings/string_piece.h" |
24 #include "base/strings/string_util.h" | 25 #include "base/strings/string_util.h" |
25 #include "base/strings/utf_string_conversions.h" | 26 #include "base/strings/utf_string_conversions.h" |
26 #include "gin/array_buffer.h" | 27 #include "gin/array_buffer.h" |
27 #include "gin/public/gin_embedders.h" | 28 #include "gin/public/gin_embedders.h" |
28 #include "gin/public/isolate_holder.h" | 29 #include "gin/public/isolate_holder.h" |
29 #include "pdf/draw_utils.h" | 30 #include "pdf/draw_utils.h" |
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 // XFA may require |form_| to outlive |doc_|, so shut down in that order. | 648 // XFA may require |form_| to outlive |doc_|, so shut down in that order. |
648 FPDF_CloseDocument(doc_); | 649 FPDF_CloseDocument(doc_); |
649 FPDFDOC_ExitFormFillEnvironment(form_); | 650 FPDFDOC_ExitFormFillEnvironment(form_); |
650 #else | 651 #else |
651 // Normally |doc_| should outlive |form_|. | 652 // Normally |doc_| should outlive |form_|. |
652 FPDFDOC_ExitFormFillEnvironment(form_); | 653 FPDFDOC_ExitFormFillEnvironment(form_); |
653 FPDF_CloseDocument(doc_); | 654 FPDF_CloseDocument(doc_); |
654 #endif | 655 #endif |
655 } | 656 } |
656 FPDFAvail_Destroy(fpdf_availability_); | 657 FPDFAvail_Destroy(fpdf_availability_); |
657 | |
658 base::STLDeleteElements(&pages_); | |
659 } | 658 } |
660 | 659 |
661 #if defined(PDF_ENABLE_XFA) | 660 #if defined(PDF_ENABLE_XFA) |
662 | 661 |
663 void PDFiumEngine::Form_EmailTo(FPDF_FORMFILLINFO* param, | 662 void PDFiumEngine::Form_EmailTo(FPDF_FORMFILLINFO* param, |
664 FPDF_FILEHANDLER* file_handler, | 663 FPDF_FILEHANDLER* file_handler, |
665 FPDF_WIDESTRING to, | 664 FPDF_WIDESTRING to, |
666 FPDF_WIDESTRING subject, | 665 FPDF_WIDESTRING subject, |
667 FPDF_WIDESTRING cc, | 666 FPDF_WIDESTRING cc, |
668 FPDF_WIDESTRING bcc, | 667 FPDF_WIDESTRING bcc, |
(...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1600 } else if (event.GetClickCount() == 2 || | 1599 } else if (event.GetClickCount() == 2 || |
1601 event.GetClickCount() == 3) { | 1600 event.GetClickCount() == 3) { |
1602 OnMultipleClick(event.GetClickCount(), page_index, char_index); | 1601 OnMultipleClick(event.GetClickCount(), page_index, char_index); |
1603 } | 1602 } |
1604 | 1603 |
1605 return true; | 1604 return true; |
1606 } | 1605 } |
1607 | 1606 |
1608 void PDFiumEngine::OnSingleClick(int page_index, int char_index) { | 1607 void PDFiumEngine::OnSingleClick(int page_index, int char_index) { |
1609 SetSelecting(true); | 1608 SetSelecting(true); |
1610 selection_.push_back(PDFiumRange(pages_[page_index], char_index, 0)); | 1609 selection_.push_back(PDFiumRange(pages_[page_index].get(), char_index, 0)); |
1611 } | 1610 } |
1612 | 1611 |
1613 void PDFiumEngine::OnMultipleClick(int click_count, | 1612 void PDFiumEngine::OnMultipleClick(int click_count, |
1614 int page_index, | 1613 int page_index, |
1615 int char_index) { | 1614 int char_index) { |
1616 // It would be more efficient if the SDK could support finding a space, but | 1615 // It would be more efficient if the SDK could support finding a space, but |
1617 // now it doesn't. | 1616 // now it doesn't. |
1618 int start_index = char_index; | 1617 int start_index = char_index; |
1619 do { | 1618 do { |
1620 base::char16 cur = pages_[page_index]->GetCharAtIndex(start_index); | 1619 base::char16 cur = pages_[page_index]->GetCharAtIndex(start_index); |
1621 // For double click, we want to select one word so we look for whitespace | 1620 // For double click, we want to select one word so we look for whitespace |
1622 // boundaries. For triple click, we want the whole line. | 1621 // boundaries. For triple click, we want the whole line. |
1623 if (cur == '\n' || (click_count == 2 && (cur == ' ' || cur == '\t'))) | 1622 if (cur == '\n' || (click_count == 2 && (cur == ' ' || cur == '\t'))) |
1624 break; | 1623 break; |
1625 } while (--start_index >= 0); | 1624 } while (--start_index >= 0); |
1626 if (start_index) | 1625 if (start_index) |
1627 start_index++; | 1626 start_index++; |
1628 | 1627 |
1629 int end_index = char_index; | 1628 int end_index = char_index; |
1630 int total = pages_[page_index]->GetCharCount(); | 1629 int total = pages_[page_index]->GetCharCount(); |
1631 while (end_index++ <= total) { | 1630 while (end_index++ <= total) { |
1632 base::char16 cur = pages_[page_index]->GetCharAtIndex(end_index); | 1631 base::char16 cur = pages_[page_index]->GetCharAtIndex(end_index); |
1633 if (cur == '\n' || (click_count == 2 && (cur == ' ' || cur == '\t'))) | 1632 if (cur == '\n' || (click_count == 2 && (cur == ' ' || cur == '\t'))) |
1634 break; | 1633 break; |
1635 } | 1634 } |
1636 | 1635 |
1637 selection_.push_back(PDFiumRange( | 1636 selection_.push_back(PDFiumRange(pages_[page_index].get(), start_index, |
1638 pages_[page_index], start_index, end_index - start_index)); | 1637 end_index - start_index)); |
1639 } | 1638 } |
1640 | 1639 |
1641 bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) { | 1640 bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) { |
1642 if (event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_LEFT && | 1641 if (event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_LEFT && |
1643 event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_MIDDLE) { | 1642 event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_MIDDLE) { |
1644 return false; | 1643 return false; |
1645 } | 1644 } |
1646 | 1645 |
1647 int page_index = -1; | 1646 int page_index = -1; |
1648 int char_index = -1; | 1647 int char_index = -1; |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1784 } else { | 1783 } else { |
1785 count = char_index - selection_[last].char_index() - 1; | 1784 count = char_index - selection_[last].char_index() - 1; |
1786 } | 1785 } |
1787 selection_[last].SetCharCount(count); | 1786 selection_[last].SetCharCount(count); |
1788 } else if (selection_[last].page_index() < page_index) { | 1787 } else if (selection_[last].page_index() < page_index) { |
1789 // Selecting into the next page. | 1788 // Selecting into the next page. |
1790 | 1789 |
1791 // First make sure that there are no gaps in selection, i.e. if mousedown on | 1790 // First make sure that there are no gaps in selection, i.e. if mousedown on |
1792 // page one but we only get mousemove over page three, we want page two. | 1791 // page one but we only get mousemove over page three, we want page two. |
1793 for (int i = selection_[last].page_index() + 1; i < page_index; ++i) { | 1792 for (int i = selection_[last].page_index() + 1; i < page_index; ++i) { |
1794 selection_.push_back(PDFiumRange(pages_[i], 0, | 1793 selection_.push_back( |
1795 pages_[i]->GetCharCount())); | 1794 PDFiumRange(pages_[i].get(), 0, pages_[i]->GetCharCount())); |
1796 } | 1795 } |
1797 | 1796 |
1798 int count = pages_[selection_[last].page_index()]->GetCharCount(); | 1797 int count = pages_[selection_[last].page_index()]->GetCharCount(); |
1799 selection_[last].SetCharCount(count - selection_[last].char_index()); | 1798 selection_[last].SetCharCount(count - selection_[last].char_index()); |
1800 selection_.push_back(PDFiumRange(pages_[page_index], 0, char_index)); | 1799 selection_.push_back(PDFiumRange(pages_[page_index].get(), 0, char_index)); |
1801 } else { | 1800 } else { |
1802 // Selecting into the previous page. | 1801 // Selecting into the previous page. |
1803 // The selection's char_index is 0-based, so the character count is one | 1802 // The selection's char_index is 0-based, so the character count is one |
1804 // more than the index. The character count needs to be negative to | 1803 // more than the index. The character count needs to be negative to |
1805 // indicate a backwards selection. | 1804 // indicate a backwards selection. |
1806 selection_[last].SetCharCount(-(selection_[last].char_index() + 1)); | 1805 selection_[last].SetCharCount(-(selection_[last].char_index() + 1)); |
1807 | 1806 |
1808 // First make sure that there are no gaps in selection, i.e. if mousedown on | 1807 // First make sure that there are no gaps in selection, i.e. if mousedown on |
1809 // page three but we only get mousemove over page one, we want page two. | 1808 // page three but we only get mousemove over page one, we want page two. |
1810 for (int i = selection_[last].page_index() - 1; i > page_index; --i) { | 1809 for (int i = selection_[last].page_index() - 1; i > page_index; --i) { |
1811 selection_.push_back(PDFiumRange(pages_[i], 0, | 1810 selection_.push_back( |
1812 pages_[i]->GetCharCount())); | 1811 PDFiumRange(pages_[i].get(), 0, pages_[i]->GetCharCount())); |
1813 } | 1812 } |
1814 | 1813 |
1815 int count = pages_[page_index]->GetCharCount(); | 1814 int count = pages_[page_index]->GetCharCount(); |
1816 selection_.push_back( | 1815 selection_.push_back( |
1817 PDFiumRange(pages_[page_index], count, count - char_index)); | 1816 PDFiumRange(pages_[page_index].get(), count, count - char_index)); |
1818 } | 1817 } |
1819 | 1818 |
1820 return true; | 1819 return true; |
1821 } | 1820 } |
1822 | 1821 |
1823 bool PDFiumEngine::OnKeyDown(const pp::KeyboardInputEvent& event) { | 1822 bool PDFiumEngine::OnKeyDown(const pp::KeyboardInputEvent& event) { |
1824 if (last_page_mouse_down_ == -1) | 1823 if (last_page_mouse_down_ == -1) |
1825 return false; | 1824 return false; |
1826 | 1825 |
1827 bool rv = !!FORM_OnKeyDown( | 1826 bool rv = !!FORM_OnKeyDown( |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1972 unsigned long flags = case_sensitive ? FPDF_MATCHCASE : 0; | 1971 unsigned long flags = case_sensitive ? FPDF_MATCHCASE : 0; |
1973 FPDF_SCHHANDLE find = FPDFText_FindStart( | 1972 FPDF_SCHHANDLE find = FPDFText_FindStart( |
1974 pages_[current_page]->GetTextPage(), | 1973 pages_[current_page]->GetTextPage(), |
1975 reinterpret_cast<const unsigned short*>(term.c_str()), | 1974 reinterpret_cast<const unsigned short*>(term.c_str()), |
1976 flags, character_to_start_searching_from); | 1975 flags, character_to_start_searching_from); |
1977 | 1976 |
1978 // Note: since we search one page at a time, we don't find matches across | 1977 // Note: since we search one page at a time, we don't find matches across |
1979 // page boundaries. We could do this manually ourself, but it seems low | 1978 // page boundaries. We could do this manually ourself, but it seems low |
1980 // priority since Reader itself doesn't do it. | 1979 // priority since Reader itself doesn't do it. |
1981 while (FPDFText_FindNext(find)) { | 1980 while (FPDFText_FindNext(find)) { |
1982 PDFiumRange result(pages_[current_page], | 1981 PDFiumRange result(pages_[current_page].get(), |
1983 FPDFText_GetSchResultIndex(find), | 1982 FPDFText_GetSchResultIndex(find), |
1984 FPDFText_GetSchCount(find)); | 1983 FPDFText_GetSchCount(find)); |
1985 | 1984 |
1986 if (!first_search && | 1985 if (!first_search && |
1987 last_character_index_to_search_ != -1 && | 1986 last_character_index_to_search_ != -1 && |
1988 result.page_index() == last_page_to_search_ && | 1987 result.page_index() == last_page_to_search_ && |
1989 result.char_index() >= last_character_index_to_search_) { | 1988 result.char_index() >= last_character_index_to_search_) { |
1990 break; | 1989 break; |
1991 } | 1990 } |
1992 | 1991 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2029 page_text.c_str(), term.c_str(), case_sensitive, &results); | 2028 page_text.c_str(), term.c_str(), case_sensitive, &results); |
2030 for (const auto& result : results) { | 2029 for (const auto& result : results) { |
2031 // Need to map the indexes from the page text, which may have generated | 2030 // Need to map the indexes from the page text, which may have generated |
2032 // characters like space etc, to character indices from the page. | 2031 // characters like space etc, to character indices from the page. |
2033 int temp_start = result.start_index + character_to_start_searching_from; | 2032 int temp_start = result.start_index + character_to_start_searching_from; |
2034 int start = FPDFText_GetCharIndexFromTextIndex( | 2033 int start = FPDFText_GetCharIndexFromTextIndex( |
2035 pages_[current_page]->GetTextPage(), temp_start); | 2034 pages_[current_page]->GetTextPage(), temp_start); |
2036 int end = FPDFText_GetCharIndexFromTextIndex( | 2035 int end = FPDFText_GetCharIndexFromTextIndex( |
2037 pages_[current_page]->GetTextPage(), | 2036 pages_[current_page]->GetTextPage(), |
2038 temp_start + result.length); | 2037 temp_start + result.length); |
2039 AddFindResult(PDFiumRange(pages_[current_page], start, end - start)); | 2038 AddFindResult(PDFiumRange(pages_[current_page].get(), start, end - start)); |
2040 } | 2039 } |
2041 } | 2040 } |
2042 | 2041 |
2043 void PDFiumEngine::AddFindResult(const PDFiumRange& result) { | 2042 void PDFiumEngine::AddFindResult(const PDFiumRange& result) { |
2044 // Figure out where to insert the new location, since we could have | 2043 // Figure out where to insert the new location, since we could have |
2045 // started searching midway and now we wrapped. | 2044 // started searching midway and now we wrapped. |
2046 size_t result_index; | 2045 size_t result_index; |
2047 int page_index = result.page_index(); | 2046 int page_index = result.page_index(); |
2048 int char_index = result.char_index(); | 2047 int char_index = result.char_index(); |
2049 for (result_index = 0; result_index < find_results_.size(); ++result_index) { | 2048 for (result_index = 0; result_index < find_results_.size(); ++result_index) { |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2257 return true; | 2256 return true; |
2258 } | 2257 } |
2259 } | 2258 } |
2260 | 2259 |
2261 void PDFiumEngine::SelectAll() { | 2260 void PDFiumEngine::SelectAll() { |
2262 SelectionChangeInvalidator selection_invalidator(this); | 2261 SelectionChangeInvalidator selection_invalidator(this); |
2263 | 2262 |
2264 selection_.clear(); | 2263 selection_.clear(); |
2265 for (const auto& page : pages_) { | 2264 for (const auto& page : pages_) { |
2266 if (page->available()) | 2265 if (page->available()) |
2267 selection_.push_back(PDFiumRange(page, 0, page->GetCharCount())); | 2266 selection_.push_back(PDFiumRange(page.get(), 0, page->GetCharCount())); |
2268 } | 2267 } |
2269 } | 2268 } |
2270 | 2269 |
2271 int PDFiumEngine::GetNumberOfPages() { | 2270 int PDFiumEngine::GetNumberOfPages() { |
2272 return pages_.size(); | 2271 return pages_.size(); |
2273 } | 2272 } |
2274 | 2273 |
2275 pp::VarArray PDFiumEngine::GetBookmarks() { | 2274 pp::VarArray PDFiumEngine::GetBookmarks() { |
2276 pp::VarDictionary dict = TraverseBookmarks(doc_, nullptr, 0); | 2275 pp::VarDictionary dict = TraverseBookmarks(doc_, nullptr, 0); |
2277 // The root bookmark contains no useful information. | 2276 // The root bookmark contains no useful information. |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2399 DCHECK_NE(num_pages, 0); | 2398 DCHECK_NE(num_pages, 0); |
2400 | 2399 |
2401 if (!doc_) | 2400 if (!doc_) |
2402 return; | 2401 return; |
2403 | 2402 |
2404 selection_.clear(); | 2403 selection_.clear(); |
2405 pending_pages_.clear(); | 2404 pending_pages_.clear(); |
2406 | 2405 |
2407 // Delete all pages except the first one. | 2406 // Delete all pages except the first one. |
2408 while (pages_.size() > 1) { | 2407 while (pages_.size() > 1) { |
2409 delete pages_.back(); | |
2410 pages_.pop_back(); | 2408 pages_.pop_back(); |
2411 FPDFPage_Delete(doc_, pages_.size()); | 2409 FPDFPage_Delete(doc_, pages_.size()); |
2412 } | 2410 } |
2413 | 2411 |
2414 // Calculate document size and all page sizes. | 2412 // Calculate document size and all page sizes. |
2415 std::vector<pp::Rect> page_rects; | 2413 std::vector<pp::Rect> page_rects; |
2416 pp::Size page_size = GetPageSize(0); | 2414 pp::Size page_size = GetPageSize(0); |
2417 page_size.Enlarge(kPageShadowLeft + kPageShadowRight, | 2415 page_size.Enlarge(kPageShadowLeft + kPageShadowRight, |
2418 kPageShadowTop + kPageShadowBottom); | 2416 kPageShadowTop + kPageShadowBottom); |
2419 pp::Size old_document_size = document_size_; | 2417 pp::Size old_document_size = document_size_; |
(...skipping 15 matching lines...) Expand all Loading... |
2435 pp::Rect page_rect(page_rects[i]); | 2433 pp::Rect page_rect(page_rects[i]); |
2436 page_rect.Inset(kPageShadowLeft, kPageShadowTop, | 2434 page_rect.Inset(kPageShadowLeft, kPageShadowTop, |
2437 kPageShadowRight, kPageShadowBottom); | 2435 kPageShadowRight, kPageShadowBottom); |
2438 double width_in_points = ConvertUnitDouble(page_rect.width(), | 2436 double width_in_points = ConvertUnitDouble(page_rect.width(), |
2439 kPixelsPerInch, | 2437 kPixelsPerInch, |
2440 kPointsPerInch); | 2438 kPointsPerInch); |
2441 double height_in_points = ConvertUnitDouble(page_rect.height(), | 2439 double height_in_points = ConvertUnitDouble(page_rect.height(), |
2442 kPixelsPerInch, | 2440 kPixelsPerInch, |
2443 kPointsPerInch); | 2441 kPointsPerInch); |
2444 FPDFPage_New(doc_, i, width_in_points, height_in_points); | 2442 FPDFPage_New(doc_, i, width_in_points, height_in_points); |
2445 pages_.push_back(new PDFiumPage(this, i, page_rect, true)); | 2443 pages_.push_back(base::MakeUnique<PDFiumPage>(this, i, page_rect, true)); |
2446 } | 2444 } |
2447 | 2445 |
2448 CalculateVisiblePages(); | 2446 CalculateVisiblePages(); |
2449 if (document_size_ != old_document_size) | 2447 if (document_size_ != old_document_size) |
2450 client_->DocumentSizeUpdated(document_size_); | 2448 client_->DocumentSizeUpdated(document_size_); |
2451 } | 2449 } |
2452 | 2450 |
2453 void PDFiumEngine::LoadDocument() { | 2451 void PDFiumEngine::LoadDocument() { |
2454 // Check if the document is ready for loading. If it isn't just bail for now, | 2452 // Check if the document is ready for loading. If it isn't just bail for now, |
2455 // we will call LoadDocument() again later. | 2453 // we will call LoadDocument() again later. |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2628 page_rects[i].set_x((document_size_.width() - page_rects[i].width()) / 2); | 2626 page_rects[i].set_x((document_size_.width() - page_rects[i].width()) / 2); |
2629 pp::Rect page_rect(page_rects[i]); | 2627 pp::Rect page_rect(page_rects[i]); |
2630 page_rect.Inset(kPageShadowLeft, kPageShadowTop, | 2628 page_rect.Inset(kPageShadowLeft, kPageShadowTop, |
2631 kPageShadowRight, kPageShadowBottom); | 2629 kPageShadowRight, kPageShadowBottom); |
2632 if (reload) { | 2630 if (reload) { |
2633 pages_[i]->set_rect(page_rect); | 2631 pages_[i]->set_rect(page_rect); |
2634 } else { | 2632 } else { |
2635 // The page is marked as not being available even if |doc_complete| is | 2633 // The page is marked as not being available even if |doc_complete| is |
2636 // true because FPDFAvail_IsPageAvail() still has to be called for this | 2634 // true because FPDFAvail_IsPageAvail() still has to be called for this |
2637 // page, which will be done in FinishLoadingDocument(). | 2635 // page, which will be done in FinishLoadingDocument(). |
2638 pages_.push_back(new PDFiumPage(this, i, page_rect, false)); | 2636 pages_.push_back(base::MakeUnique<PDFiumPage>(this, i, page_rect, false)); |
2639 } | 2637 } |
2640 } | 2638 } |
2641 | 2639 |
2642 CalculateVisiblePages(); | 2640 CalculateVisiblePages(); |
2643 if (document_size_ != old_document_size) | 2641 if (document_size_ != old_document_size) |
2644 client_->DocumentSizeUpdated(document_size_); | 2642 client_->DocumentSizeUpdated(document_size_); |
2645 } | 2643 } |
2646 | 2644 |
2647 void PDFiumEngine::CalculateVisiblePages() { | 2645 void PDFiumEngine::CalculateVisiblePages() { |
2648 // Clear pending requests queue, since it may contain requests to the pages | 2646 // Clear pending requests queue, since it may contain requests to the pages |
(...skipping 1359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4008 FPDF_DOCUMENT doc = | 4006 FPDF_DOCUMENT doc = |
4009 FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, nullptr); | 4007 FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, nullptr); |
4010 if (!doc) | 4008 if (!doc) |
4011 return false; | 4009 return false; |
4012 bool success = FPDF_GetPageSizeByIndex(doc, page_number, width, height) != 0; | 4010 bool success = FPDF_GetPageSizeByIndex(doc, page_number, width, height) != 0; |
4013 FPDF_CloseDocument(doc); | 4011 FPDF_CloseDocument(doc); |
4014 return success; | 4012 return success; |
4015 } | 4013 } |
4016 | 4014 |
4017 } // namespace chrome_pdf | 4015 } // namespace chrome_pdf |
OLD | NEW |