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:
Haojian Wu 2015-05-11 20:14:07 +08:00
Родитель 30d815e28f
Коммит abd97a7513
5 изменённых файлов: 118 добавлений и 3 удалений

Просмотреть файл

@ -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)