1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
11 #include "base/command_line.h"
12 #include "base/logging.h"
13 #include "pdf/instance.h"
14 #include "pdf/out_of_process_instance.h"
15 #include "ppapi/c/ppp.h"
16 #include "ppapi/cpp/private/pdf.h"
17 #include "v8/include/v8.h"
19 bool g_sdk_initialized_via_pepper
= false;
21 // The Mac release builds discard CreateModule and the entire PDFModule
22 // definition because they are not referenced here. This causes the Pepper
23 // exports (PPP_GetInterface etc) to not be exported. So we force the linker
24 // to include this code by using __attribute__((used)).
26 #define PDF_USED __attribute__((used))
33 void HandleInvalidParameter(const wchar_t* expression
,
34 const wchar_t* function
,
38 // Do the same as Chrome's CHECK(false) which is undefined.
39 ::base::debug::BreakDebugger();
43 void HandlePureVirtualCall() {
44 // Do the same as Chrome's CHECK(false) which is undefined.
45 ::base::debug::BreakDebugger();
50 BOOL APIENTRY
DllMain(HMODULE module
, DWORD reason_for_call
, LPVOID reserved
) {
51 if (reason_for_call
== DLL_PROCESS_ATTACH
) {
52 // On windows following handlers work only inside module. So breakpad in
53 // chrome.dll does not catch that. To avoid linking related code or
54 // duplication breakpad_win.cc::InitCrashReporter() just catch errors here
55 // and crash in a way interceptable by breakpad of parent module.
56 _set_invalid_parameter_handler(HandleInvalidParameter
);
57 _set_purecall_handler(HandlePureVirtualCall
);
59 #if defined(ARCH_CPU_X86_64) && _MSC_VER <= 1800
60 // VS2013's CRT only checks the existence of FMA3 instructions, not the
61 // enabled-ness of them at the OS level (this is fixed in VS2015). We force
62 // off usage of FMA3 instructions in the CRT to avoid using that path and
63 // hitting illegal instructions when running on CPUs that support FMA3, but
64 // OSs that don't. Because we use the static library CRT we have to call
65 // this function once in each DLL.
66 // See http://crbug.com/436603.
68 #endif // ARCH_CPU_X86_64 && _MSC_VER <= 1800
77 PDF_USED Module
* CreateModule() {
78 return new chrome_pdf::PDFModule();
83 namespace chrome_pdf
{
85 PDFModule::PDFModule() {
88 PDFModule::~PDFModule() {
89 if (g_sdk_initialized_via_pepper
) {
90 chrome_pdf::ShutdownSDK();
91 g_sdk_initialized_via_pepper
= false;
95 bool PDFModule::Init() {
99 pp::Instance
* PDFModule::CreateInstance(PP_Instance instance
) {
100 if (!g_sdk_initialized_via_pepper
) {
101 v8::StartupData natives
;
102 v8::StartupData snapshot
;
103 pp::PDF::GetV8ExternalSnapshotData(pp::InstanceHandle(instance
),
104 &natives
.data
, &natives
.raw_size
,
105 &snapshot
.data
, &snapshot
.raw_size
);
107 v8::V8::SetNativesDataBlob(&natives
);
108 v8::V8::SetSnapshotDataBlob(&snapshot
);
110 if (!chrome_pdf::InitializeSDK())
112 g_sdk_initialized_via_pepper
= true;
115 if (pp::PDF::IsOutOfProcess(pp::InstanceHandle(instance
)))
116 return new OutOfProcessInstance(instance
);
117 return new Instance(instance
);
120 } // namespace chrome_pdf
124 // TODO(sanjeevr): It might make sense to provide more stateful wrappers over
125 // the internal PDF SDK (such as LoadDocument, LoadPage etc). Determine if we
126 // need to provide this.
127 // Wrapper exports over the PDF engine that can be used by an external module
128 // such as Chrome (since Chrome cannot directly pull in PDFium sources).
130 // |pdf_buffer| is the buffer that contains the entire PDF document to be
132 // |buffer_size| is the size of |pdf_buffer| in bytes.
133 // |page_number| is the 0-based index of the page to be rendered.
134 // |dc| is the device context to render into.
135 // |dpi_x| and |dpi_y| are the x and y resolutions respectively. If either
136 // value is -1, the dpi from the DC will be used.
137 // |bounds_origin_x|, |bounds_origin_y|, |bounds_width| and |bounds_height|
138 // specify a bounds rectangle within the DC in which to render the PDF
140 // |fit_to_bounds| specifies whether the output should be shrunk to fit the
141 // supplied bounds if the page size is larger than the bounds in any
142 // dimension. If this is false, parts of the PDF page that lie outside
143 // the bounds will be clipped.
144 // |stretch_to_bounds| specifies whether the output should be stretched to fit
145 // the supplied bounds if the page size is smaller than the bounds in any
147 // If both |fit_to_bounds| and |stretch_to_bounds| are true, then
148 // |fit_to_bounds| is honored first.
149 // |keep_aspect_ratio| If any scaling is to be done is true, this flag
150 // specifies whether the original aspect ratio of the page should be
151 // preserved while scaling.
152 // |center_in_bounds| specifies whether the final image (after any scaling is
153 // done) should be centered within the given bounds.
154 // |autorotate| specifies whether the final image should be rotated to match
156 // Returns false if the document or the page number are not valid.
157 PP_EXPORT
bool RenderPDFPageToDC(const void* pdf_buffer
,
168 bool stretch_to_bounds
,
169 bool keep_aspect_ratio
,
170 bool center_in_bounds
,
172 if (!g_sdk_initialized_via_pepper
) {
173 if (!chrome_pdf::InitializeSDK()) {
177 scoped_ptr
<chrome_pdf::PDFEngineExports
> engine_exports(
178 chrome_pdf::PDFEngineExports::Create());
179 chrome_pdf::PDFEngineExports::RenderingSettings
settings(
180 dpi_x
, dpi_y
, pp::Rect(bounds_origin_x
, bounds_origin_y
, bounds_width
,
182 fit_to_bounds
, stretch_to_bounds
, keep_aspect_ratio
, center_in_bounds
,
184 bool ret
= engine_exports
->RenderPDFPageToDC(pdf_buffer
, buffer_size
,
185 page_number
, settings
, dc
);
186 if (!g_sdk_initialized_via_pepper
) {
187 chrome_pdf::ShutdownSDK();
194 // |page_count| and |max_page_width| are optional and can be NULL.
195 // Returns false if the document is not valid.
197 bool GetPDFDocInfo(const void* pdf_buffer
,
198 int buffer_size
, int* page_count
,
199 double* max_page_width
) {
200 if (!g_sdk_initialized_via_pepper
) {
201 if (!chrome_pdf::InitializeSDK())
204 scoped_ptr
<chrome_pdf::PDFEngineExports
> engine_exports(
205 chrome_pdf::PDFEngineExports::Create());
206 bool ret
= engine_exports
->GetPDFDocInfo(
207 pdf_buffer
, buffer_size
, page_count
, max_page_width
);
208 if (!g_sdk_initialized_via_pepper
) {
209 chrome_pdf::ShutdownSDK();
214 // Gets the dimensions of a specific page in a document.
215 // |pdf_buffer| is the buffer that contains the entire PDF document to be
217 // |pdf_buffer_size| is the size of |pdf_buffer| in bytes.
218 // |page_number| is the page number that the function will get the dimensions
220 // |width| is the output for the width of the page in points.
221 // |height| is the output for the height of the page in points.
222 // Returns false if the document or the page number are not valid.
224 bool GetPDFPageSizeByIndex(const void* pdf_buffer
,
225 int pdf_buffer_size
, int page_number
,
226 double* width
, double* height
) {
227 if (!g_sdk_initialized_via_pepper
) {
228 if (!chrome_pdf::InitializeSDK())
231 scoped_ptr
<chrome_pdf::PDFEngineExports
> engine_exports(
232 chrome_pdf::PDFEngineExports::Create());
233 bool ret
= engine_exports
->GetPDFPageSizeByIndex(
234 pdf_buffer
, pdf_buffer_size
, page_number
, width
, height
);
235 if (!g_sdk_initialized_via_pepper
)
236 chrome_pdf::ShutdownSDK();
240 // Renders PDF page into 4-byte per pixel BGRA color bitmap.
241 // |pdf_buffer| is the buffer that contains the entire PDF document to be
243 // |pdf_buffer_size| is the size of |pdf_buffer| in bytes.
244 // |page_number| is the 0-based index of the page to be rendered.
245 // |bitmap_buffer| is the output buffer for bitmap.
246 // |bitmap_width| is the width of the output bitmap.
247 // |bitmap_height| is the height of the output bitmap.
248 // |dpi| is the resolutions.
249 // |autorotate| specifies whether the final image should be rotated to match
251 // Returns false if the document or the page number are not valid.
253 bool RenderPDFPageToBitmap(const void* pdf_buffer
,
261 if (!g_sdk_initialized_via_pepper
) {
262 if (!chrome_pdf::InitializeSDK())
265 scoped_ptr
<chrome_pdf::PDFEngineExports
> engine_exports(
266 chrome_pdf::PDFEngineExports::Create());
267 chrome_pdf::PDFEngineExports::RenderingSettings
settings(
268 dpi
, dpi
, pp::Rect(bitmap_width
, bitmap_height
), true, false, true, true,
270 bool ret
= engine_exports
->RenderPDFPageToBitmap(
271 pdf_buffer
, pdf_buffer_size
, page_number
, settings
, bitmap_buffer
);
272 if (!g_sdk_initialized_via_pepper
) {
273 chrome_pdf::ShutdownSDK();