Load pdf component dynamically.
Ship pdf as dll library, electron only loads pdf.dll when calling print API. In this way, the developer who don't need print feature can safe remove the pdf.dll in saving their binary size.
This commit is contained in:
Родитель
30d815e28f
Коммит
abd97a7513
|
@ -64,6 +64,12 @@ void AtomMainDelegate::PreSandboxStartup() {
|
|||
std::string process_type = command_line->GetSwitchValueASCII(
|
||||
switches::kProcessType);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
if (process_type == switches::kUtilityProcess) {
|
||||
AtomContentUtilityClient::PreSandboxStartup();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Only append arguments for browser process.
|
||||
if (!process_type.empty())
|
||||
return;
|
||||
|
|
|
@ -71,4 +71,9 @@ void AtomContentUtilityClient::OnStartupPing() {
|
|||
// Don't release the process, we assume further messages are on the way.
|
||||
}
|
||||
|
||||
// static
|
||||
void AtomContentUtilityClient::PreSandboxStartup() {
|
||||
PrintingHandler::PreSandboxStartup();
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -31,6 +31,7 @@ class AtomContentUtilityClient : public content::ContentUtilityClient {
|
|||
void UtilityThreadStarted() override;
|
||||
bool OnMessageReceived(const IPC::Message& message) override;
|
||||
|
||||
static void PreSandboxStartup();
|
||||
|
||||
static void set_max_ipc_message_size_for_test(int64_t max_message_size) {
|
||||
max_ipc_message_size_ = max_message_size;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "base/scoped_native_library.h"
|
||||
#include "chrome/common/print_messages.h"
|
||||
#include "content/public/utility/utility_thread.h"
|
||||
#include "pdf/pdf.h"
|
||||
#include "printing/page_range.h"
|
||||
#include "printing/pdf_render_settings.h"
|
||||
|
||||
|
@ -30,12 +29,111 @@ void ReleaseProcessIfNeeded() {
|
|||
content::UtilityThread::Get()->ReleaseProcessIfNeeded();
|
||||
}
|
||||
|
||||
class PdfFunctions {
|
||||
public:
|
||||
PdfFunctions() : get_pdf_doc_info_func_(NULL),
|
||||
render_pdf_to_dc_func_(NULL) {}
|
||||
|
||||
bool Init() {
|
||||
base::FilePath pdf_module_path(FILE_PATH_LITERAL("pdf.dll"));
|
||||
pdf_lib_.Reset(base::LoadNativeLibrary(pdf_module_path, NULL));
|
||||
if (!pdf_lib_.is_valid()) {
|
||||
LOG(WARNING) << "Couldn't load PDF plugin";
|
||||
return false;
|
||||
}
|
||||
|
||||
get_pdf_doc_info_func_ =
|
||||
reinterpret_cast<GetPDFDocInfoProc>(
|
||||
pdf_lib_.GetFunctionPointer("GetPDFDocInfo"));
|
||||
LOG_IF(WARNING, !get_pdf_doc_info_func_) << "Missing GetPDFDocInfo";
|
||||
|
||||
render_pdf_to_dc_func_ =
|
||||
reinterpret_cast<RenderPDFPageToDCProc>(
|
||||
pdf_lib_.GetFunctionPointer("RenderPDFPageToDC"));
|
||||
LOG_IF(WARNING, !render_pdf_to_dc_func_) << "Missing RenderPDFPageToDC";
|
||||
|
||||
if (!get_pdf_doc_info_func_ || !render_pdf_to_dc_func_) {
|
||||
Reset();
|
||||
}
|
||||
|
||||
return IsValid();
|
||||
}
|
||||
|
||||
bool IsValid() const {
|
||||
return pdf_lib_.is_valid();
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
pdf_lib_.Reset(NULL);
|
||||
}
|
||||
|
||||
bool GetPDFDocInfo(const void* pdf_buffer,
|
||||
int buffer_size,
|
||||
int* page_count,
|
||||
double* max_page_width) {
|
||||
if (!get_pdf_doc_info_func_)
|
||||
return false;
|
||||
return get_pdf_doc_info_func_(pdf_buffer, buffer_size, page_count,
|
||||
max_page_width);
|
||||
}
|
||||
|
||||
bool RenderPDFPageToDC(const void* pdf_buffer,
|
||||
int buffer_size,
|
||||
int page_number,
|
||||
HDC dc,
|
||||
int dpi,
|
||||
int bounds_origin_x,
|
||||
int bounds_origin_y,
|
||||
int bounds_width,
|
||||
int bounds_height,
|
||||
bool fit_to_bounds,
|
||||
bool stretch_to_bounds,
|
||||
bool keep_aspect_ratio,
|
||||
bool center_in_bounds,
|
||||
bool autorotate) {
|
||||
if (!render_pdf_to_dc_func_)
|
||||
return false;
|
||||
return render_pdf_to_dc_func_(pdf_buffer, buffer_size, page_number,
|
||||
dc, dpi, bounds_origin_x,
|
||||
bounds_origin_y, bounds_width, bounds_height,
|
||||
fit_to_bounds, stretch_to_bounds,
|
||||
keep_aspect_ratio, center_in_bounds,
|
||||
autorotate);
|
||||
}
|
||||
|
||||
private:
|
||||
// Exported by PDF plugin.
|
||||
typedef bool (*GetPDFDocInfoProc)(const void* pdf_buffer,
|
||||
int buffer_size, int* page_count,
|
||||
double* max_page_width);
|
||||
typedef bool (*RenderPDFPageToDCProc)(
|
||||
const void* pdf_buffer, int buffer_size, int page_number, HDC dc,
|
||||
int dpi, int bounds_origin_x, int bounds_origin_y,
|
||||
int bounds_width, int bounds_height, bool fit_to_bounds,
|
||||
bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds,
|
||||
bool autorotate);
|
||||
|
||||
RenderPDFPageToDCProc render_pdf_to_dc_func_;
|
||||
GetPDFDocInfoProc get_pdf_doc_info_func_;
|
||||
|
||||
base::ScopedNativeLibrary pdf_lib_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PdfFunctions);
|
||||
};
|
||||
|
||||
base::LazyInstance<PdfFunctions> g_pdf_lib = LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
} // namespace
|
||||
|
||||
PrintingHandler::PrintingHandler() {}
|
||||
|
||||
PrintingHandler::~PrintingHandler() {}
|
||||
|
||||
// static
|
||||
void PrintingHandler::PreSandboxStartup() {
|
||||
g_pdf_lib.Get().Init();
|
||||
}
|
||||
|
||||
bool PrintingHandler::OnMessageReceived(const IPC::Message& message) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(PrintingHandler, message)
|
||||
|
@ -80,6 +178,9 @@ void PrintingHandler::OnRenderPDFPagesToMetafileStop() {
|
|||
}
|
||||
|
||||
int PrintingHandler::LoadPDF(base::File pdf_file) {
|
||||
if (!g_pdf_lib.Get().IsValid())
|
||||
return 0;
|
||||
|
||||
int64 length64 = pdf_file.GetLength();
|
||||
if (length64 <= 0 || length64 > std::numeric_limits<int>::max())
|
||||
return 0;
|
||||
|
@ -90,7 +191,7 @@ int PrintingHandler::LoadPDF(base::File pdf_file) {
|
|||
return 0;
|
||||
|
||||
int total_page_count = 0;
|
||||
if (!chrome_pdf::GetPDFDocInfo(
|
||||
if (!g_pdf_lib.Get().GetPDFDocInfo(
|
||||
&pdf_data_.front(), pdf_data_.size(), &total_page_count, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -119,7 +220,7 @@ bool PrintingHandler::RenderPdfPageToMetafile(int page_number,
|
|||
// The underlying metafile is of type Emf and ignores the arguments passed
|
||||
// to StartPage.
|
||||
metafile.StartPage(gfx::Size(), gfx::Rect(), 1);
|
||||
if (!chrome_pdf::RenderPDFPageToDC(
|
||||
if (!g_pdf_lib.Get().RenderPDFPageToDC(
|
||||
&pdf_data_.front(),
|
||||
pdf_data_.size(),
|
||||
page_number,
|
||||
|
|
|
@ -30,6 +30,8 @@ class PrintingHandler : public UtilityMessageHandler {
|
|||
// IPC::Listener:
|
||||
bool OnMessageReceived(const IPC::Message& message) override;
|
||||
|
||||
static void PrintingHandler::PreSandboxStartup();
|
||||
|
||||
private:
|
||||
// IPC message handlers.
|
||||
#if defined(OS_WIN)
|
||||
|
|
Загрузка…
Ссылка в новой задаче