| 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 | 8 |
| 9 #include "base/i18n/icu_encoding_detection.h" | 9 #include "base/i18n/icu_encoding_detection.h" |
| 10 #include "base/i18n/icu_string_conversions.h" | 10 #include "base/i18n/icu_string_conversions.h" |
| (...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 } | 518 } |
| 519 | 519 |
| 520 // Returns a VarDictionary (representing a bookmark), which in turn contains | 520 // Returns a VarDictionary (representing a bookmark), which in turn contains |
| 521 // child VarDictionaries (representing the child bookmarks). | 521 // child VarDictionaries (representing the child bookmarks). |
| 522 // If NULL is passed in as the bookmark then we traverse from the "root". | 522 // If NULL is passed in as the bookmark then we traverse from the "root". |
| 523 // Note that the "root" bookmark contains no useful information. | 523 // Note that the "root" bookmark contains no useful information. |
| 524 pp::VarDictionary TraverseBookmarks(FPDF_DOCUMENT doc, FPDF_BOOKMARK bookmark) { | 524 pp::VarDictionary TraverseBookmarks(FPDF_DOCUMENT doc, FPDF_BOOKMARK bookmark) { |
| 525 pp::VarDictionary dict; | 525 pp::VarDictionary dict; |
| 526 base::string16 title; | 526 base::string16 title; |
| 527 unsigned long buffer_size = FPDFBookmark_GetTitle(bookmark, NULL, 0); | 527 unsigned long buffer_size = FPDFBookmark_GetTitle(bookmark, NULL, 0); |
| 528 size_t title_length = base::checked_cast<size_t>(buffer_size) / | 528 if (buffer_size > 0) { |
| 529 sizeof(base::string16::value_type); | 529 PDFiumAPIStringBufferSizeInBytesAdapter<base::string16> api_string_adapter( |
| 530 if (title_length > 0) { | 530 &title, buffer_size, true); |
| 531 PDFiumAPIStringBufferAdapter<base::string16> api_string_adapter( | 531 api_string_adapter.Close(FPDFBookmark_GetTitle( |
| 532 &title, title_length, true); | 532 bookmark, api_string_adapter.GetData(), buffer_size)); |
| 533 void* data = api_string_adapter.GetData(); | |
| 534 FPDFBookmark_GetTitle(bookmark, data, buffer_size); | |
| 535 api_string_adapter.Close(title_length); | |
| 536 } | 533 } |
| 537 dict.Set(pp::Var("title"), pp::Var(base::UTF16ToUTF8(title))); | 534 dict.Set(pp::Var("title"), pp::Var(base::UTF16ToUTF8(title))); |
| 538 | 535 |
| 539 FPDF_DEST dest = FPDFBookmark_GetDest(doc, bookmark); | 536 FPDF_DEST dest = FPDFBookmark_GetDest(doc, bookmark); |
| 540 // Some bookmarks don't have a page to select. | 537 // Some bookmarks don't have a page to select. |
| 541 if (dest) { | 538 if (dest) { |
| 542 int page_index = FPDFDest_GetPageIndex(doc, dest); | 539 int page_index = FPDFDest_GetPageIndex(doc, dest); |
| 543 dict.Set(pp::Var("page"), pp::Var(page_index)); | 540 dict.Set(pp::Var("page"), pp::Var(page_index)); |
| 544 } | 541 } |
| 545 | 542 |
| 546 pp::VarArray children; | 543 pp::VarArray children; |
| 547 int child_index = 0; | 544 int child_index = 0; |
| 548 for (FPDF_BOOKMARK child_bookmark = FPDFBookmark_GetFirstChild(doc, bookmark); | 545 for (FPDF_BOOKMARK child_bookmark = FPDFBookmark_GetFirstChild(doc, bookmark); |
| 549 child_bookmark != NULL; | 546 child_bookmark != NULL; |
| 550 child_bookmark = FPDFBookmark_GetNextSibling(doc, child_bookmark)) { | 547 child_bookmark = FPDFBookmark_GetNextSibling(doc, child_bookmark)) { |
| 551 children.Set(child_index, TraverseBookmarks(doc, child_bookmark)); | 548 children.Set(child_index, TraverseBookmarks(doc, child_bookmark)); |
| 552 child_index++; | 549 child_index++; |
| 553 } | 550 } |
| 554 dict.Set(pp::Var("children"), children); | 551 dict.Set(pp::Var("children"), children); |
| 555 return dict; | 552 return dict; |
| 556 } | 553 } |
| 557 | 554 |
| 555 std::string GetDocumentMetadata(FPDF_DOCUMENT doc, const std::string& key) { |
| 556 size_t size = FPDF_GetMetaText(doc, key.c_str(), nullptr, 0); |
| 557 if (size == 0) |
| 558 return std::string(); |
| 559 |
| 560 base::string16 value; |
| 561 PDFiumAPIStringBufferSizeInBytesAdapter<base::string16> string_adapter( |
| 562 &value, size, false); |
| 563 string_adapter.Close( |
| 564 FPDF_GetMetaText(doc, key.c_str(), string_adapter.GetData(), size)); |
| 565 return base::UTF16ToUTF8(value); |
| 566 } |
| 567 |
| 558 } // namespace | 568 } // namespace |
| 559 | 569 |
| 560 bool InitializeSDK() { | 570 bool InitializeSDK() { |
| 561 FPDF_InitLibrary(); | 571 FPDF_InitLibrary(); |
| 562 | 572 |
| 563 #if defined(OS_LINUX) | 573 #if defined(OS_LINUX) |
| 564 // Font loading doesn't work in the renderer sandbox in Linux. | 574 // Font loading doesn't work in the renderer sandbox in Linux. |
| 565 FPDF_SetSystemFontInfo(&g_font_info); | 575 FPDF_SetSystemFontInfo(&g_font_info); |
| 566 #endif | 576 #endif |
| 567 | 577 |
| (...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 } | 1179 } |
| 1170 | 1180 |
| 1171 void PDFiumEngine::SetScrollPosition(const pp::Point& position) { | 1181 void PDFiumEngine::SetScrollPosition(const pp::Point& position) { |
| 1172 position_ = position; | 1182 position_ = position; |
| 1173 } | 1183 } |
| 1174 | 1184 |
| 1175 bool PDFiumEngine::IsProgressiveLoad() { | 1185 bool PDFiumEngine::IsProgressiveLoad() { |
| 1176 return doc_loader_.is_partial_document(); | 1186 return doc_loader_.is_partial_document(); |
| 1177 } | 1187 } |
| 1178 | 1188 |
| 1189 std::string PDFiumEngine::GetMetadata(const std::string& key) { |
| 1190 return GetDocumentMetadata(doc(), key); |
| 1191 } |
| 1192 |
| 1179 void PDFiumEngine::OnPartialDocumentLoaded() { | 1193 void PDFiumEngine::OnPartialDocumentLoaded() { |
| 1180 file_access_.m_FileLen = doc_loader_.document_size(); | 1194 file_access_.m_FileLen = doc_loader_.document_size(); |
| 1181 fpdf_availability_ = FPDFAvail_Create(&file_availability_, &file_access_); | 1195 fpdf_availability_ = FPDFAvail_Create(&file_availability_, &file_access_); |
| 1182 DCHECK(fpdf_availability_); | 1196 DCHECK(fpdf_availability_); |
| 1183 | 1197 |
| 1184 // Currently engine does not deal efficiently with some non-linearized files. | 1198 // Currently engine does not deal efficiently with some non-linearized files. |
| 1185 // See http://code.google.com/p/chromium/issues/detail?id=59400 | 1199 // See http://code.google.com/p/chromium/issues/detail?id=59400 |
| 1186 // To improve user experience we download entire file for non-linearized PDF. | 1200 // To improve user experience we download entire file for non-linearized PDF. |
| 1187 if (!FPDFAvail_IsLinearized(fpdf_availability_)) { | 1201 if (!FPDFAvail_IsLinearized(fpdf_availability_)) { |
| 1188 doc_loader_.RequestData(0, doc_loader_.document_size()); | 1202 doc_loader_.RequestData(0, doc_loader_.document_size()); |
| (...skipping 2735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3924 IntersectClipRect(dc, settings.bounds.x(), settings.bounds.y(), | 3938 IntersectClipRect(dc, settings.bounds.x(), settings.bounds.y(), |
| 3925 settings.bounds.x() + settings.bounds.width(), | 3939 settings.bounds.x() + settings.bounds.width(), |
| 3926 settings.bounds.y() + settings.bounds.height()); | 3940 settings.bounds.y() + settings.bounds.height()); |
| 3927 | 3941 |
| 3928 // A temporary hack. PDFs generated by Cairo (used by Chrome OS to generate | 3942 // A temporary hack. PDFs generated by Cairo (used by Chrome OS to generate |
| 3929 // a PDF output from a webpage) result in very large metafiles and the | 3943 // a PDF output from a webpage) result in very large metafiles and the |
| 3930 // rendering using FPDF_RenderPage is incorrect. In this case, render as a | 3944 // rendering using FPDF_RenderPage is incorrect. In this case, render as a |
| 3931 // bitmap. Note that this code does not kick in for PDFs printed from Chrome | 3945 // bitmap. Note that this code does not kick in for PDFs printed from Chrome |
| 3932 // because in that case we create a temp PDF first before printing and this | 3946 // because in that case we create a temp PDF first before printing and this |
| 3933 // temp PDF does not have a creator string that starts with "cairo". | 3947 // temp PDF does not have a creator string that starts with "cairo". |
| 3934 base::string16 creator; | 3948 bool use_bitmap = false; |
| 3935 size_t buffer_bytes = FPDF_GetMetaText(doc, "Creator", NULL, 0); | 3949 if (base::StartsWith(GetDocumentMetadata(doc, "Creator"), "cairo", |
| 3936 if (buffer_bytes > 1) { | 3950 base::CompareCase::INSENSITIVE_ASCII)) { |
| 3937 FPDF_GetMetaText(doc, "Creator", | 3951 use_bitmap = true; |
| 3938 base::WriteInto(&creator, buffer_bytes + 1), buffer_bytes); | |
| 3939 } | 3952 } |
| 3940 bool use_bitmap = false; | |
| 3941 if (base::StartsWith(creator, L"cairo", base::CompareCase::INSENSITIVE_ASCII)) | |
| 3942 use_bitmap = true; | |
| 3943 | 3953 |
| 3944 // Another temporary hack. Some PDFs seems to render very slowly if | 3954 // Another temporary hack. Some PDFs seems to render very slowly if |
| 3945 // FPDF_RenderPage is directly used on a printer DC. I suspect it is | 3955 // FPDF_RenderPage is directly used on a printer DC. I suspect it is |
| 3946 // because of the code to talk Postscript directly to the printer if | 3956 // because of the code to talk Postscript directly to the printer if |
| 3947 // the printer supports this. Need to discuss this with PDFium. For now, | 3957 // the printer supports this. Need to discuss this with PDFium. For now, |
| 3948 // render to a bitmap and then blit the bitmap to the DC if we have been | 3958 // render to a bitmap and then blit the bitmap to the DC if we have been |
| 3949 // supplied a printer DC. | 3959 // supplied a printer DC. |
| 3950 int device_type = GetDeviceCaps(dc, TECHNOLOGY); | 3960 int device_type = GetDeviceCaps(dc, TECHNOLOGY); |
| 3951 if (use_bitmap || | 3961 if (use_bitmap || |
| 3952 (device_type == DT_RASPRINTER) || (device_type == DT_PLOTTER)) { | 3962 (device_type == DT_RASPRINTER) || (device_type == DT_PLOTTER)) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4052 double* height) { | 4062 double* height) { |
| 4053 FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, NULL); | 4063 FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, NULL); |
| 4054 if (!doc) | 4064 if (!doc) |
| 4055 return false; | 4065 return false; |
| 4056 bool success = FPDF_GetPageSizeByIndex(doc, page_number, width, height) != 0; | 4066 bool success = FPDF_GetPageSizeByIndex(doc, page_number, width, height) != 0; |
| 4057 FPDF_CloseDocument(doc); | 4067 FPDF_CloseDocument(doc); |
| 4058 return success; | 4068 return success; |
| 4059 } | 4069 } |
| 4060 | 4070 |
| 4061 } // namespace chrome_pdf | 4071 } // namespace chrome_pdf |
| OLD | NEW |