OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 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 | 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/pdf.h" | 5 #include "pdf/pdf.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <windows.h> | 8 #include <windows.h> |
9 #endif | 9 #endif |
10 | 10 |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "pdf/instance.h" | 13 #include "pdf/instance.h" |
14 #include "pdf/out_of_process_instance.h" | 14 #include "pdf/out_of_process_instance.h" |
15 #include "ppapi/c/ppp.h" | 15 #include "ppapi/c/ppp.h" |
| 16 #include "ppapi/cpp/private/internal_module.h" |
16 #include "ppapi/cpp/private/pdf.h" | 17 #include "ppapi/cpp/private/pdf.h" |
17 #include "v8/include/v8.h" | 18 #include "v8/include/v8.h" |
18 | 19 |
19 bool g_sdk_initialized_via_pepper = false; | 20 bool g_sdk_initialized_via_pepper = false; |
20 | 21 |
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)). | |
25 #if __GNUC__ >= 4 | |
26 #define PDF_USED __attribute__((used)) | |
27 #else | |
28 #define PDF_USED | |
29 #endif | |
30 | |
31 #if defined(OS_WIN) | |
32 | |
33 void HandleInvalidParameter(const wchar_t* expression, | |
34 const wchar_t* function, | |
35 const wchar_t* file, | |
36 unsigned int line, | |
37 uintptr_t reserved) { | |
38 // Do the same as Chrome's CHECK(false) which is undefined. | |
39 ::base::debug::BreakDebugger(); | |
40 return; | |
41 } | |
42 | |
43 void HandlePureVirtualCall() { | |
44 // Do the same as Chrome's CHECK(false) which is undefined. | |
45 ::base::debug::BreakDebugger(); | |
46 return; | |
47 } | |
48 | |
49 | |
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); | |
58 | |
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. | |
67 _set_FMA3_enable(0); | |
68 #endif // ARCH_CPU_X86_64 && _MSC_VER <= 1800 | |
69 } | |
70 return TRUE; | |
71 } | |
72 | |
73 #endif | |
74 | |
75 namespace pp { | |
76 | |
77 PDF_USED Module* CreateModule() { | |
78 return new chrome_pdf::PDFModule(); | |
79 } | |
80 | |
81 } // namespace pp | |
82 | |
83 namespace chrome_pdf { | 22 namespace chrome_pdf { |
84 | 23 |
85 PDFModule::PDFModule() { | 24 PDFModule::PDFModule() { |
86 } | 25 } |
87 | 26 |
88 PDFModule::~PDFModule() { | 27 PDFModule::~PDFModule() { |
89 if (g_sdk_initialized_via_pepper) { | 28 if (g_sdk_initialized_via_pepper) { |
90 chrome_pdf::ShutdownSDK(); | 29 chrome_pdf::ShutdownSDK(); |
91 g_sdk_initialized_via_pepper = false; | 30 g_sdk_initialized_via_pepper = false; |
92 } | 31 } |
(...skipping 17 matching lines...) Expand all Loading... |
110 if (!chrome_pdf::InitializeSDK()) | 49 if (!chrome_pdf::InitializeSDK()) |
111 return NULL; | 50 return NULL; |
112 g_sdk_initialized_via_pepper = true; | 51 g_sdk_initialized_via_pepper = true; |
113 } | 52 } |
114 | 53 |
115 if (pp::PDF::IsOutOfProcess(pp::InstanceHandle(instance))) | 54 if (pp::PDF::IsOutOfProcess(pp::InstanceHandle(instance))) |
116 return new OutOfProcessInstance(instance); | 55 return new OutOfProcessInstance(instance); |
117 return new Instance(instance); | 56 return new Instance(instance); |
118 } | 57 } |
119 | 58 |
120 } // namespace chrome_pdf | |
121 | 59 |
122 extern "C" { | 60 // Implementation of Global PPP functions --------------------------------- |
| 61 int32_t PPP_InitializeModule(PP_Module module_id, |
| 62 PPB_GetInterface get_browser_interface) { |
| 63 PDFModule* module = new PDFModule(); |
| 64 if (!module->InternalInit(module_id, get_browser_interface)) { |
| 65 delete module; |
| 66 return PP_ERROR_FAILED; |
| 67 } |
123 | 68 |
124 // TODO(sanjeevr): It might make sense to provide more stateful wrappers over | 69 pp::InternalSetModuleSingleton(module); |
125 // the internal PDF SDK (such as LoadDocument, LoadPage etc). Determine if we | 70 return PP_OK; |
126 // need to provide this. | 71 } |
127 // Wrapper exports over the PDF engine that can be used by an external module | 72 |
128 // such as Chrome (since Chrome cannot directly pull in PDFium sources). | 73 void PPP_ShutdownModule() { |
| 74 delete pp::Module::Get(); |
| 75 pp::InternalSetModuleSingleton(NULL); |
| 76 } |
| 77 |
| 78 const void* PPP_GetInterface(const char* interface_name) { |
| 79 if (!pp::Module::Get()) |
| 80 return NULL; |
| 81 return pp::Module::Get()->GetPluginInterface(interface_name); |
| 82 } |
| 83 |
129 #if defined(OS_WIN) | 84 #if defined(OS_WIN) |
130 // |pdf_buffer| is the buffer that contains the entire PDF document to be | 85 bool RenderPDFPageToDC(const void* pdf_buffer, |
131 // rendered. | |
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 | |
139 // page. | |
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 | |
146 // dimension. | |
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 | |
155 // the output bound. | |
156 // Returns false if the document or the page number are not valid. | |
157 PP_EXPORT bool RenderPDFPageToDC(const void* pdf_buffer, | |
158 int buffer_size, | 86 int buffer_size, |
159 int page_number, | 87 int page_number, |
160 HDC dc, | 88 HDC dc, |
161 int dpi_x, | 89 int dpi, |
162 int dpi_y, | |
163 int bounds_origin_x, | 90 int bounds_origin_x, |
164 int bounds_origin_y, | 91 int bounds_origin_y, |
165 int bounds_width, | 92 int bounds_width, |
166 int bounds_height, | 93 int bounds_height, |
167 bool fit_to_bounds, | 94 bool fit_to_bounds, |
168 bool stretch_to_bounds, | 95 bool stretch_to_bounds, |
169 bool keep_aspect_ratio, | 96 bool keep_aspect_ratio, |
170 bool center_in_bounds, | 97 bool center_in_bounds, |
171 bool autorotate) { | 98 bool autorotate) { |
172 if (!g_sdk_initialized_via_pepper) { | 99 if (!g_sdk_initialized_via_pepper) { |
173 if (!chrome_pdf::InitializeSDK()) { | 100 if (!chrome_pdf::InitializeSDK()) { |
174 return false; | 101 return false; |
175 } | 102 } |
176 } | 103 } |
177 scoped_ptr<chrome_pdf::PDFEngineExports> engine_exports( | 104 scoped_ptr<chrome_pdf::PDFEngineExports> engine_exports( |
178 chrome_pdf::PDFEngineExports::Create()); | 105 chrome_pdf::PDFEngineExports::Create()); |
179 chrome_pdf::PDFEngineExports::RenderingSettings settings( | 106 chrome_pdf::PDFEngineExports::RenderingSettings settings( |
180 dpi_x, dpi_y, pp::Rect(bounds_origin_x, bounds_origin_y, bounds_width, | 107 dpi, dpi, pp::Rect(bounds_origin_x, bounds_origin_y, bounds_width, |
181 bounds_height), | 108 bounds_height), |
182 fit_to_bounds, stretch_to_bounds, keep_aspect_ratio, center_in_bounds, | 109 fit_to_bounds, stretch_to_bounds, keep_aspect_ratio, center_in_bounds, |
183 autorotate); | 110 autorotate); |
184 bool ret = engine_exports->RenderPDFPageToDC(pdf_buffer, buffer_size, | 111 bool ret = engine_exports->RenderPDFPageToDC(pdf_buffer, buffer_size, |
185 page_number, settings, dc); | 112 page_number, settings, dc); |
186 if (!g_sdk_initialized_via_pepper) { | 113 if (!g_sdk_initialized_via_pepper) { |
187 chrome_pdf::ShutdownSDK(); | 114 chrome_pdf::ShutdownSDK(); |
188 } | 115 } |
189 return ret; | 116 return ret; |
190 } | 117 } |
191 | 118 |
192 #endif // OS_WIN | 119 #endif // OS_WIN |
193 | 120 |
194 // |page_count| and |max_page_width| are optional and can be NULL. | |
195 // Returns false if the document is not valid. | |
196 PDF_USED PP_EXPORT | |
197 bool GetPDFDocInfo(const void* pdf_buffer, | 121 bool GetPDFDocInfo(const void* pdf_buffer, |
198 int buffer_size, int* page_count, | 122 int buffer_size, int* page_count, |
199 double* max_page_width) { | 123 double* max_page_width) { |
200 if (!g_sdk_initialized_via_pepper) { | 124 if (!g_sdk_initialized_via_pepper) { |
201 if (!chrome_pdf::InitializeSDK()) | 125 if (!chrome_pdf::InitializeSDK()) |
202 return false; | 126 return false; |
203 } | 127 } |
204 scoped_ptr<chrome_pdf::PDFEngineExports> engine_exports( | 128 scoped_ptr<chrome_pdf::PDFEngineExports> engine_exports( |
205 chrome_pdf::PDFEngineExports::Create()); | 129 chrome_pdf::PDFEngineExports::Create()); |
206 bool ret = engine_exports->GetPDFDocInfo( | 130 bool ret = engine_exports->GetPDFDocInfo( |
207 pdf_buffer, buffer_size, page_count, max_page_width); | 131 pdf_buffer, buffer_size, page_count, max_page_width); |
208 if (!g_sdk_initialized_via_pepper) { | 132 if (!g_sdk_initialized_via_pepper) { |
209 chrome_pdf::ShutdownSDK(); | 133 chrome_pdf::ShutdownSDK(); |
210 } | 134 } |
211 return ret; | 135 return ret; |
212 } | 136 } |
213 | 137 |
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 | |
216 // rendered. | |
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 | |
219 // of. | |
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. | |
223 PDF_USED PP_EXPORT | |
224 bool GetPDFPageSizeByIndex(const void* pdf_buffer, | 138 bool GetPDFPageSizeByIndex(const void* pdf_buffer, |
225 int pdf_buffer_size, int page_number, | 139 int pdf_buffer_size, int page_number, |
226 double* width, double* height) { | 140 double* width, double* height) { |
227 if (!g_sdk_initialized_via_pepper) { | 141 if (!g_sdk_initialized_via_pepper) { |
228 if (!chrome_pdf::InitializeSDK()) | 142 if (!chrome_pdf::InitializeSDK()) |
229 return false; | 143 return false; |
230 } | 144 } |
231 scoped_ptr<chrome_pdf::PDFEngineExports> engine_exports( | 145 scoped_ptr<chrome_pdf::PDFEngineExports> engine_exports( |
232 chrome_pdf::PDFEngineExports::Create()); | 146 chrome_pdf::PDFEngineExports::Create()); |
233 bool ret = engine_exports->GetPDFPageSizeByIndex( | 147 bool ret = engine_exports->GetPDFPageSizeByIndex( |
234 pdf_buffer, pdf_buffer_size, page_number, width, height); | 148 pdf_buffer, pdf_buffer_size, page_number, width, height); |
235 if (!g_sdk_initialized_via_pepper) | 149 if (!g_sdk_initialized_via_pepper) |
236 chrome_pdf::ShutdownSDK(); | 150 chrome_pdf::ShutdownSDK(); |
237 return ret; | 151 return ret; |
238 } | 152 } |
239 | 153 |
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 | |
242 // rendered. | |
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 | |
250 // the output bound. | |
251 // Returns false if the document or the page number are not valid. | |
252 PDF_USED PP_EXPORT | |
253 bool RenderPDFPageToBitmap(const void* pdf_buffer, | 154 bool RenderPDFPageToBitmap(const void* pdf_buffer, |
254 int pdf_buffer_size, | 155 int pdf_buffer_size, |
255 int page_number, | 156 int page_number, |
256 void* bitmap_buffer, | 157 void* bitmap_buffer, |
257 int bitmap_width, | 158 int bitmap_width, |
258 int bitmap_height, | 159 int bitmap_height, |
259 int dpi, | 160 int dpi, |
260 bool autorotate) { | 161 bool autorotate) { |
261 if (!g_sdk_initialized_via_pepper) { | 162 if (!g_sdk_initialized_via_pepper) { |
262 if (!chrome_pdf::InitializeSDK()) | 163 if (!chrome_pdf::InitializeSDK()) |
263 return false; | 164 return false; |
264 } | 165 } |
265 scoped_ptr<chrome_pdf::PDFEngineExports> engine_exports( | 166 scoped_ptr<chrome_pdf::PDFEngineExports> engine_exports( |
266 chrome_pdf::PDFEngineExports::Create()); | 167 chrome_pdf::PDFEngineExports::Create()); |
267 chrome_pdf::PDFEngineExports::RenderingSettings settings( | 168 chrome_pdf::PDFEngineExports::RenderingSettings settings( |
268 dpi, dpi, pp::Rect(bitmap_width, bitmap_height), true, false, true, true, | 169 dpi, dpi, pp::Rect(bitmap_width, bitmap_height), true, false, true, true, |
269 autorotate); | 170 autorotate); |
270 bool ret = engine_exports->RenderPDFPageToBitmap( | 171 bool ret = engine_exports->RenderPDFPageToBitmap( |
271 pdf_buffer, pdf_buffer_size, page_number, settings, bitmap_buffer); | 172 pdf_buffer, pdf_buffer_size, page_number, settings, bitmap_buffer); |
272 if (!g_sdk_initialized_via_pepper) { | 173 if (!g_sdk_initialized_via_pepper) { |
273 chrome_pdf::ShutdownSDK(); | 174 chrome_pdf::ShutdownSDK(); |
274 } | 175 } |
275 return ret; | 176 return ret; |
276 } | 177 } |
277 | 178 |
278 } // extern "C" | 179 } // namespace chrome_pdf |
OLD | NEW |