OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include "pdf/pdf.h" |
| 6 |
| 7 #if defined(OS_WIN) |
| 8 #include <windows.h> |
| 9 #endif |
| 10 |
| 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 |
| 18 bool g_sdk_initialized_via_pepper = false; |
| 19 |
| 20 // The Mac release builds discard CreateModule and the entire PDFModule |
| 21 // definition because they are not referenced here. This causes the Pepper |
| 22 // exports (PPP_GetInterface etc) to not be exported. So we force the linker |
| 23 // to include this code by using __attribute__((used)). |
| 24 #if __GNUC__ >= 4 |
| 25 #define PDF_USED __attribute__((used)) |
| 26 #else |
| 27 #define PDF_USED |
| 28 #endif |
| 29 |
| 30 #if defined(OS_WIN) |
| 31 HMODULE g_hmodule; |
| 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 g_hmodule = module; |
| 52 if (reason_for_call == DLL_PROCESS_ATTACH) { |
| 53 // On windows following handlers work only inside module. So breakpad in |
| 54 // chrome.dll does not catch that. To avoid linking related code or |
| 55 // duplication breakpad_win.cc::InitCrashReporter() just catch errors here |
| 56 // and crash in a way interceptable by breakpad of parent module. |
| 57 _set_invalid_parameter_handler(HandleInvalidParameter); |
| 58 _set_purecall_handler(HandlePureVirtualCall); |
| 59 } |
| 60 return TRUE; |
| 61 } |
| 62 |
| 63 #endif |
| 64 |
| 65 namespace pp { |
| 66 |
| 67 PDF_USED Module* CreateModule() { |
| 68 return new chrome_pdf::PDFModule(); |
| 69 } |
| 70 |
| 71 } // namespace pp |
| 72 |
| 73 namespace chrome_pdf { |
| 74 |
| 75 PDFModule::PDFModule() { |
| 76 } |
| 77 |
| 78 PDFModule::~PDFModule() { |
| 79 if (g_sdk_initialized_via_pepper) { |
| 80 chrome_pdf::ShutdownSDK(); |
| 81 g_sdk_initialized_via_pepper = false; |
| 82 } |
| 83 } |
| 84 |
| 85 bool PDFModule::Init() { |
| 86 return true; |
| 87 } |
| 88 |
| 89 pp::Instance* PDFModule::CreateInstance(PP_Instance instance) { |
| 90 if (!g_sdk_initialized_via_pepper) { |
| 91 void* data = NULL; |
| 92 #if defined(OS_WIN) |
| 93 data = g_hmodule; |
| 94 #endif |
| 95 if (!chrome_pdf::InitializeSDK(data)) |
| 96 return NULL; |
| 97 g_sdk_initialized_via_pepper = true; |
| 98 } |
| 99 |
| 100 if (pp::PDF::IsOutOfProcess(pp::InstanceHandle(instance))) |
| 101 return new OutOfProcessInstance(instance); |
| 102 return new Instance(instance); |
| 103 } |
| 104 |
| 105 } // namespace chrome_pdf |
| 106 |
| 107 extern "C" { |
| 108 |
| 109 // TODO(sanjeevr): It might make sense to provide more stateful wrappers over |
| 110 // the internal PDF SDK (such as LoadDocument, LoadPage etc). Determine if we |
| 111 // need to provide this. |
| 112 // Wrapper exports over the PDF engine that can be used by an external module |
| 113 // such as Chrome (since Chrome cannot directly pull in PDFium sources). |
| 114 #if defined(OS_WIN) |
| 115 // |pdf_buffer| is the buffer that contains the entire PDF document to be |
| 116 // rendered. |
| 117 // |buffer_size| is the size of pdf_buffer in bytes. |
| 118 // |page_number| is the 0-based index of the page to be rendered. |
| 119 // |dc| is the device context to render into. |
| 120 // |dpi_x| and |dpi_y| are the x and y resolutions respectively. If either value |
| 121 // is -1, the dpi from the DC will be used. |
| 122 // |bounds_origin_x|, |bounds_origin_y|, |bounds_width| and |bounds_height| |
| 123 // specify a bounds rectangle within the DC in which to render the PDF page. |
| 124 // |fit_to_bounds| specifies whether the output should be shrunk to fit the |
| 125 // supplied bounds if the page size is larger than the bounds in any |
| 126 // dimension. If this is false, parts of the PDF page that lie outside the |
| 127 // bounds will be clipped. |
| 128 // |stretch_to_bounds| specifies whether the output should be stretched to fit |
| 129 // the supplied bounds if the page size is smaller than the bounds in any |
| 130 // dimension. |
| 131 // If both |fit_to_bounds| and |stretch_to_bounds| are true, then |
| 132 // |fit_to_bounds| is honored first. |
| 133 // |keep_aspect_ratio| If any scaling is to be done is true, this flag specifies |
| 134 // whether the original aspect ratio of the page should be preserved while |
| 135 // scaling. |
| 136 // |center_in_bounds| specifies whether the final image (after any scaling is |
| 137 // done) should be centered within the given bounds. |
| 138 // |autorotate| specifies whether the final image should be rotated to match |
| 139 // the output bound. |
| 140 // Returns false if the document or the page number are not valid. |
| 141 PP_EXPORT bool RenderPDFPageToDC(const void* pdf_buffer, |
| 142 int buffer_size, |
| 143 int page_number, |
| 144 HDC dc, |
| 145 int dpi_x, |
| 146 int dpi_y, |
| 147 int bounds_origin_x, |
| 148 int bounds_origin_y, |
| 149 int bounds_width, |
| 150 int bounds_height, |
| 151 bool fit_to_bounds, |
| 152 bool stretch_to_bounds, |
| 153 bool keep_aspect_ratio, |
| 154 bool center_in_bounds, |
| 155 bool autorotate) { |
| 156 if (!g_sdk_initialized_via_pepper) { |
| 157 if (!chrome_pdf::InitializeSDK(g_hmodule)) { |
| 158 return false; |
| 159 } |
| 160 } |
| 161 scoped_ptr<chrome_pdf::PDFEngineExports> engine_exports( |
| 162 chrome_pdf::PDFEngineExports::Create()); |
| 163 chrome_pdf::PDFEngineExports::RenderingSettings settings( |
| 164 dpi_x, dpi_y, pp::Rect(bounds_origin_x, bounds_origin_y, bounds_width, |
| 165 bounds_height), |
| 166 fit_to_bounds, stretch_to_bounds, keep_aspect_ratio, center_in_bounds, |
| 167 autorotate); |
| 168 bool ret = engine_exports->RenderPDFPageToDC(pdf_buffer, buffer_size, |
| 169 page_number, settings, dc); |
| 170 if (!g_sdk_initialized_via_pepper) { |
| 171 chrome_pdf::ShutdownSDK(); |
| 172 } |
| 173 return ret; |
| 174 } |
| 175 |
| 176 #endif // OS_WIN |
| 177 |
| 178 // |page_count| and |max_page_width| are optional and can be NULL. |
| 179 // Returns false if the document is not valid. |
| 180 PDF_USED PP_EXPORT |
| 181 bool GetPDFDocInfo(const void* pdf_buffer, |
| 182 int buffer_size, int* page_count, |
| 183 double* max_page_width) { |
| 184 if (!g_sdk_initialized_via_pepper) { |
| 185 void* data = NULL; |
| 186 #if defined(OS_WIN) |
| 187 data = g_hmodule; |
| 188 #endif |
| 189 if (!chrome_pdf::InitializeSDK(data)) |
| 190 return false; |
| 191 } |
| 192 scoped_ptr<chrome_pdf::PDFEngineExports> engine_exports( |
| 193 chrome_pdf::PDFEngineExports::Create()); |
| 194 bool ret = engine_exports->GetPDFDocInfo( |
| 195 pdf_buffer, buffer_size, page_count, max_page_width); |
| 196 if (!g_sdk_initialized_via_pepper) { |
| 197 chrome_pdf::ShutdownSDK(); |
| 198 } |
| 199 return ret; |
| 200 } |
| 201 |
| 202 // Renders PDF page into 4-byte per pixel BGRA color bitmap. |
| 203 // |pdf_buffer| is the buffer that contains the entire PDF document to be |
| 204 // rendered. |
| 205 // |pdf_buffer_size| is the size of pdf_buffer in bytes. |
| 206 // |page_number| is the 0-based index of the page to be rendered. |
| 207 // |bitmap_buffer| is the output buffer for bitmap. |
| 208 // |bitmap_width| is the width of the output bitmap. |
| 209 // |bitmap_height| is the height of the output bitmap. |
| 210 // |dpi| is the resolutions. |
| 211 // |autorotate| specifies whether the final image should be rotated to match |
| 212 // the output bound. |
| 213 // Returns false if the document or the page number are not valid. |
| 214 PDF_USED PP_EXPORT |
| 215 bool RenderPDFPageToBitmap(const void* pdf_buffer, |
| 216 int pdf_buffer_size, |
| 217 int page_number, |
| 218 void* bitmap_buffer, |
| 219 int bitmap_width, |
| 220 int bitmap_height, |
| 221 int dpi, |
| 222 bool autorotate) { |
| 223 if (!g_sdk_initialized_via_pepper) { |
| 224 void* data = NULL; |
| 225 #if defined(OS_WIN) |
| 226 data = g_hmodule; |
| 227 #endif |
| 228 if (!chrome_pdf::InitializeSDK(data)) |
| 229 return false; |
| 230 } |
| 231 scoped_ptr<chrome_pdf::PDFEngineExports> engine_exports( |
| 232 chrome_pdf::PDFEngineExports::Create()); |
| 233 chrome_pdf::PDFEngineExports::RenderingSettings settings( |
| 234 dpi, dpi, pp::Rect(bitmap_width, bitmap_height), true, false, true, true, |
| 235 autorotate); |
| 236 bool ret = engine_exports->RenderPDFPageToBitmap( |
| 237 pdf_buffer, pdf_buffer_size, page_number, settings, bitmap_buffer); |
| 238 if (!g_sdk_initialized_via_pepper) { |
| 239 chrome_pdf::ShutdownSDK(); |
| 240 } |
| 241 return ret; |
| 242 } |
| 243 |
| 244 } // extern "C" |
OLD | NEW |