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