OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 "chrome/renderer/pepper/ppb_pdf_impl.h" | |
6 | |
7 #include "base/files/scoped_file.h" | |
8 #include "base/metrics/histogram.h" | |
9 #include "base/numerics/safe_conversions.h" | |
10 #include "base/strings/utf_string_conversions.h" | |
11 #include "build/build_config.h" | |
12 #include "chrome/common/render_messages.h" | |
13 #include "chrome/renderer/printing/print_web_view_helper.h" | |
14 #include "content/app/resources/grit/content_resources.h" | |
15 #include "content/app/strings/grit/content_strings.h" | |
16 #include "content/public/common/child_process_sandbox_support_linux.h" | |
17 #include "content/public/common/referrer.h" | |
18 #include "content/public/renderer/pepper_plugin_instance.h" | |
19 #include "content/public/renderer/render_thread.h" | |
20 #include "content/public/renderer/render_view.h" | |
21 #include "ppapi/c/pp_resource.h" | |
22 #include "ppapi/c/private/ppb_pdf.h" | |
23 #include "ppapi/c/trusted/ppb_browser_font_trusted.h" | |
24 #include "ppapi/shared_impl/ppapi_globals.h" | |
25 #include "ppapi/shared_impl/resource.h" | |
26 #include "ppapi/shared_impl/resource_tracker.h" | |
27 #include "ppapi/shared_impl/var.h" | |
28 #include "third_party/WebKit/public/web/WebDocument.h" | |
29 #include "third_party/WebKit/public/web/WebElement.h" | |
30 #include "third_party/WebKit/public/web/WebLocalFrame.h" | |
31 #include "third_party/WebKit/public/web/WebPluginContainer.h" | |
32 #include "third_party/WebKit/public/web/WebView.h" | |
33 #include "third_party/icu/source/i18n/unicode/usearch.h" | |
34 #include "third_party/skia/include/core/SkBitmap.h" | |
35 #include "ui/base/l10n/l10n_util.h" | |
36 #include "ui/base/resource/resource_bundle.h" | |
37 | |
38 namespace { | |
39 | |
40 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | |
41 class PrivateFontFile : public ppapi::Resource { | |
42 public: | |
43 PrivateFontFile(PP_Instance instance, int fd) | |
44 : Resource(ppapi::OBJECT_IS_IMPL, instance), fd_(fd) {} | |
45 | |
46 bool GetFontTable(uint32_t table, void* output, uint32_t* output_length) { | |
47 size_t temp_size = static_cast<size_t>(*output_length); | |
48 bool rv = content::GetFontTable( | |
49 fd_.get(), table, 0 /* offset */, static_cast<uint8_t*>(output), | |
50 &temp_size); | |
51 *output_length = base::checked_cast<uint32_t>(temp_size); | |
52 return rv; | |
53 } | |
54 | |
55 protected: | |
56 virtual ~PrivateFontFile() {} | |
57 | |
58 private: | |
59 base::ScopedFD fd_; | |
60 }; | |
61 #endif | |
62 | |
63 struct ResourceImageInfo { | |
64 PP_ResourceImage pp_id; | |
65 int res_id; | |
66 }; | |
67 | |
68 static const ResourceImageInfo kResourceImageMap[] = { | |
69 {PP_RESOURCEIMAGE_PDF_BUTTON_FTP, IDR_PDF_BUTTON_FTP}, | |
70 {PP_RESOURCEIMAGE_PDF_BUTTON_FTP_HOVER, IDR_PDF_BUTTON_FTP_HOVER}, | |
71 {PP_RESOURCEIMAGE_PDF_BUTTON_FTP_PRESSED, IDR_PDF_BUTTON_FTP_PRESSED}, | |
72 {PP_RESOURCEIMAGE_PDF_BUTTON_FTW, IDR_PDF_BUTTON_FTW}, | |
73 {PP_RESOURCEIMAGE_PDF_BUTTON_FTW_HOVER, IDR_PDF_BUTTON_FTW_HOVER}, | |
74 {PP_RESOURCEIMAGE_PDF_BUTTON_FTW_PRESSED, IDR_PDF_BUTTON_FTW_PRESSED}, | |
75 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END, IDR_PDF_BUTTON_ZOOMIN_END}, | |
76 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END_HOVER, | |
77 IDR_PDF_BUTTON_ZOOMIN_END_HOVER}, | |
78 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END_PRESSED, | |
79 IDR_PDF_BUTTON_ZOOMIN_END_PRESSED}, | |
80 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN, IDR_PDF_BUTTON_ZOOMIN}, | |
81 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_HOVER, IDR_PDF_BUTTON_ZOOMIN_HOVER}, | |
82 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_PRESSED, IDR_PDF_BUTTON_ZOOMIN_PRESSED}, | |
83 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT, IDR_PDF_BUTTON_ZOOMOUT}, | |
84 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_HOVER, IDR_PDF_BUTTON_ZOOMOUT_HOVER}, | |
85 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_PRESSED, | |
86 IDR_PDF_BUTTON_ZOOMOUT_PRESSED}, | |
87 {PP_RESOURCEIMAGE_PDF_BUTTON_SAVE, IDR_PDF_BUTTON_SAVE}, | |
88 {PP_RESOURCEIMAGE_PDF_BUTTON_SAVE_HOVER, IDR_PDF_BUTTON_SAVE_HOVER}, | |
89 {PP_RESOURCEIMAGE_PDF_BUTTON_SAVE_PRESSED, IDR_PDF_BUTTON_SAVE_PRESSED}, | |
90 {PP_RESOURCEIMAGE_PDF_BUTTON_PRINT, IDR_PDF_BUTTON_PRINT}, | |
91 {PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_HOVER, IDR_PDF_BUTTON_PRINT_HOVER}, | |
92 {PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_PRESSED, IDR_PDF_BUTTON_PRINT_PRESSED}, | |
93 {PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_DISABLED, IDR_PDF_BUTTON_PRINT_DISABLED}, | |
94 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_0, IDR_PDF_THUMBNAIL_0}, | |
95 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_1, IDR_PDF_THUMBNAIL_1}, | |
96 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_2, IDR_PDF_THUMBNAIL_2}, | |
97 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_3, IDR_PDF_THUMBNAIL_3}, | |
98 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_4, IDR_PDF_THUMBNAIL_4}, | |
99 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_5, IDR_PDF_THUMBNAIL_5}, | |
100 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_6, IDR_PDF_THUMBNAIL_6}, | |
101 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_7, IDR_PDF_THUMBNAIL_7}, | |
102 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_8, IDR_PDF_THUMBNAIL_8}, | |
103 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_9, IDR_PDF_THUMBNAIL_9}, | |
104 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_NUM_BACKGROUND, | |
105 IDR_PDF_THUMBNAIL_NUM_BACKGROUND}, | |
106 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_0, IDR_PDF_PROGRESS_BAR_0}, | |
107 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_1, IDR_PDF_PROGRESS_BAR_1}, | |
108 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_2, IDR_PDF_PROGRESS_BAR_2}, | |
109 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_3, IDR_PDF_PROGRESS_BAR_3}, | |
110 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_4, IDR_PDF_PROGRESS_BAR_4}, | |
111 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_5, IDR_PDF_PROGRESS_BAR_5}, | |
112 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_6, IDR_PDF_PROGRESS_BAR_6}, | |
113 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_7, IDR_PDF_PROGRESS_BAR_7}, | |
114 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_8, IDR_PDF_PROGRESS_BAR_8}, | |
115 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_BACKGROUND, | |
116 IDR_PDF_PROGRESS_BAR_BACKGROUND}, | |
117 {PP_RESOURCEIMAGE_PDF_PAGE_INDICATOR_BACKGROUND, | |
118 IDR_PDF_PAGE_INDICATOR_BACKGROUND}, | |
119 {PP_RESOURCEIMAGE_PDF_PAGE_DROPSHADOW, IDR_PDF_PAGE_DROPSHADOW}, | |
120 {PP_RESOURCEIMAGE_PDF_PAN_SCROLL_ICON, IDR_PAN_SCROLL_ICON}, }; | |
121 | |
122 #if defined(ENABLE_FULL_PRINTING) | |
123 | |
124 blink::WebElement GetWebElement(PP_Instance instance_id) { | |
125 content::PepperPluginInstance* instance = | |
126 content::PepperPluginInstance::Get(instance_id); | |
127 if (!instance) | |
128 return blink::WebElement(); | |
129 return instance->GetContainer()->element(); | |
130 } | |
131 | |
132 printing::PrintWebViewHelper* GetPrintWebViewHelper( | |
133 const blink::WebElement& element) { | |
134 if (element.isNull()) | |
135 return NULL; | |
136 blink::WebView* view = element.document().frame()->view(); | |
137 content::RenderView* render_view = content::RenderView::FromWebView(view); | |
138 return printing::PrintWebViewHelper::Get(render_view); | |
139 } | |
140 | |
141 bool IsPrintingEnabled(PP_Instance instance_id) { | |
142 blink::WebElement element = GetWebElement(instance_id); | |
143 printing::PrintWebViewHelper* helper = GetPrintWebViewHelper(element); | |
144 return helper && helper->IsPrintingEnabled(); | |
145 } | |
146 | |
147 #else // ENABLE_FULL_PRINTING | |
148 | |
149 bool IsPrintingEnabled(PP_Instance instance_id) { return false; } | |
150 | |
151 #endif // ENABLE_FULL_PRINTING | |
152 | |
153 PP_Var GetLocalizedString(PP_Instance instance_id, | |
154 PP_ResourceString string_id) { | |
155 content::PepperPluginInstance* instance = | |
156 content::PepperPluginInstance::Get(instance_id); | |
157 if (!instance) | |
158 return PP_MakeUndefined(); | |
159 | |
160 std::string rv; | |
161 if (string_id == PP_RESOURCESTRING_PDFGETPASSWORD) { | |
162 rv = base::UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_NEED_PASSWORD)); | |
163 } else if (string_id == PP_RESOURCESTRING_PDFLOADING) { | |
164 rv = base::UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_PAGE_LOADING)); | |
165 } else if (string_id == PP_RESOURCESTRING_PDFLOAD_FAILED) { | |
166 rv = base::UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_PAGE_LOAD_FAILED)); | |
167 } else if (string_id == PP_RESOURCESTRING_PDFPROGRESSLOADING) { | |
168 rv = base::UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_PROGRESS_LOADING)); | |
169 } else { | |
170 NOTREACHED(); | |
171 } | |
172 | |
173 return ppapi::StringVar::StringToPPVar(rv); | |
174 } | |
175 | |
176 PP_Resource GetFontFileWithFallback( | |
177 PP_Instance instance_id, | |
178 const PP_BrowserFont_Trusted_Description* description, | |
179 PP_PrivateFontCharset charset) { | |
180 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | |
181 // Validate the instance before using it below. | |
182 if (!content::PepperPluginInstance::Get(instance_id)) | |
183 return 0; | |
184 | |
185 scoped_refptr<ppapi::StringVar> face_name( | |
186 ppapi::StringVar::FromPPVar(description->face)); | |
187 if (!face_name) | |
188 return 0; | |
189 | |
190 int fd = content::MatchFontWithFallback( | |
191 face_name->value().c_str(), | |
192 description->weight >= PP_BROWSERFONT_TRUSTED_WEIGHT_BOLD, | |
193 description->italic, | |
194 charset, | |
195 description->family); | |
196 if (fd == -1) | |
197 return 0; | |
198 | |
199 scoped_refptr<PrivateFontFile> font(new PrivateFontFile(instance_id, fd)); | |
200 | |
201 return font->GetReference(); | |
202 #else | |
203 // For trusted PPAPI plugins, this is only needed in Linux since font loading | |
204 // on Windows and Mac works through the renderer sandbox. | |
205 return 0; | |
206 #endif | |
207 } | |
208 | |
209 bool GetFontTableForPrivateFontFile(PP_Resource font_file, | |
210 uint32_t table, | |
211 void* output, | |
212 uint32_t* output_length) { | |
213 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | |
214 ppapi::Resource* resource = | |
215 ppapi::PpapiGlobals::Get()->GetResourceTracker()->GetResource(font_file); | |
216 if (!resource) | |
217 return false; | |
218 | |
219 PrivateFontFile* font = static_cast<PrivateFontFile*>(resource); | |
220 return font->GetFontTable(table, output, output_length); | |
221 #else | |
222 return false; | |
223 #endif | |
224 } | |
225 | |
226 void SearchString(PP_Instance instance, | |
227 const unsigned short* input_string, | |
228 const unsigned short* input_term, | |
229 bool case_sensitive, | |
230 PP_PrivateFindResult** results, | |
231 int* count) { | |
232 const base::char16* string = | |
233 reinterpret_cast<const base::char16*>(input_string); | |
234 const base::char16* term = reinterpret_cast<const base::char16*>(input_term); | |
235 | |
236 UErrorCode status = U_ZERO_ERROR; | |
237 UStringSearch* searcher = | |
238 usearch_open(term, | |
239 -1, | |
240 string, | |
241 -1, | |
242 content::RenderThread::Get()->GetLocale().c_str(), | |
243 0, | |
244 &status); | |
245 DCHECK(status == U_ZERO_ERROR || status == U_USING_FALLBACK_WARNING || | |
246 status == U_USING_DEFAULT_WARNING); | |
247 UCollationStrength strength = case_sensitive ? UCOL_TERTIARY : UCOL_PRIMARY; | |
248 | |
249 UCollator* collator = usearch_getCollator(searcher); | |
250 if (ucol_getStrength(collator) != strength) { | |
251 ucol_setStrength(collator, strength); | |
252 usearch_reset(searcher); | |
253 } | |
254 | |
255 status = U_ZERO_ERROR; | |
256 int match_start = usearch_first(searcher, &status); | |
257 DCHECK(status == U_ZERO_ERROR); | |
258 | |
259 std::vector<PP_PrivateFindResult> pp_results; | |
260 while (match_start != USEARCH_DONE) { | |
261 size_t matched_length = usearch_getMatchedLength(searcher); | |
262 PP_PrivateFindResult result; | |
263 result.start_index = match_start; | |
264 result.length = matched_length; | |
265 pp_results.push_back(result); | |
266 match_start = usearch_next(searcher, &status); | |
267 DCHECK(status == U_ZERO_ERROR); | |
268 } | |
269 | |
270 *count = pp_results.size(); | |
271 if (*count) { | |
272 *results = reinterpret_cast<PP_PrivateFindResult*>( | |
273 malloc(*count * sizeof(PP_PrivateFindResult))); | |
274 memcpy(*results, &pp_results[0], *count * sizeof(PP_PrivateFindResult)); | |
275 } else { | |
276 *results = NULL; | |
277 } | |
278 | |
279 usearch_close(searcher); | |
280 } | |
281 | |
282 void DidStartLoading(PP_Instance instance_id) { | |
283 content::PepperPluginInstance* instance = | |
284 content::PepperPluginInstance::Get(instance_id); | |
285 if (!instance) | |
286 return; | |
287 instance->GetRenderView()->DidStartLoading(); | |
288 } | |
289 | |
290 void DidStopLoading(PP_Instance instance_id) { | |
291 content::PepperPluginInstance* instance = | |
292 content::PepperPluginInstance::Get(instance_id); | |
293 if (!instance) | |
294 return; | |
295 instance->GetRenderView()->DidStopLoading(); | |
296 } | |
297 | |
298 void SetContentRestriction(PP_Instance instance_id, int restrictions) { | |
299 content::PepperPluginInstance* instance = | |
300 content::PepperPluginInstance::Get(instance_id); | |
301 if (!instance) | |
302 return; | |
303 instance->GetRenderView()->Send( | |
304 new ChromeViewHostMsg_PDFUpdateContentRestrictions( | |
305 instance->GetRenderView()->GetRoutingID(), restrictions)); | |
306 } | |
307 | |
308 void HistogramPDFPageCount(PP_Instance instance, int count) { | |
309 UMA_HISTOGRAM_COUNTS_10000("PDF.PageCount", count); | |
310 } | |
311 | |
312 void UserMetricsRecordAction(PP_Instance instance, PP_Var action) { | |
313 scoped_refptr<ppapi::StringVar> action_str( | |
314 ppapi::StringVar::FromPPVar(action)); | |
315 if (action_str) | |
316 content::RenderThread::Get()->RecordComputedAction(action_str->value()); | |
317 } | |
318 | |
319 void HasUnsupportedFeature(PP_Instance instance_id) { | |
320 content::PepperPluginInstance* instance = | |
321 content::PepperPluginInstance::Get(instance_id); | |
322 if (!instance) | |
323 return; | |
324 | |
325 // Only want to show an info bar if the pdf is the whole tab. | |
326 if (!instance->IsFullPagePlugin()) | |
327 return; | |
328 | |
329 blink::WebView* view = | |
330 instance->GetContainer()->element().document().frame()->view(); | |
331 content::RenderView* render_view = content::RenderView::FromWebView(view); | |
332 render_view->Send(new ChromeViewHostMsg_PDFHasUnsupportedFeature( | |
333 render_view->GetRoutingID())); | |
334 } | |
335 | |
336 void SaveAs(PP_Instance instance_id) { | |
337 content::PepperPluginInstance* instance = | |
338 content::PepperPluginInstance::Get(instance_id); | |
339 if (!instance) | |
340 return; | |
341 GURL url = instance->GetPluginURL(); | |
342 | |
343 content::RenderView* render_view = instance->GetRenderView(); | |
344 blink::WebLocalFrame* frame = | |
345 render_view->GetWebView()->mainFrame()->toWebLocalFrame(); | |
346 content::Referrer referrer(frame->document().url(), | |
347 frame->document().referrerPolicy()); | |
348 render_view->Send(new ChromeViewHostMsg_PDFSaveURLAs( | |
349 render_view->GetRoutingID(), url, referrer)); | |
350 } | |
351 | |
352 PP_Bool IsFeatureEnabled(PP_Instance instance, PP_PDFFeature feature) { | |
353 switch (feature) { | |
354 case PP_PDFFEATURE_HIDPI: | |
355 return PP_TRUE; | |
356 case PP_PDFFEATURE_PRINTING: | |
357 return IsPrintingEnabled(instance) ? PP_TRUE : PP_FALSE; | |
358 } | |
359 return PP_FALSE; | |
360 } | |
361 | |
362 PP_Resource GetResourceImageForScale(PP_Instance instance_id, | |
363 PP_ResourceImage image_id, | |
364 float scale) { | |
365 int res_id = 0; | |
366 for (size_t i = 0; i < arraysize(kResourceImageMap); ++i) { | |
367 if (kResourceImageMap[i].pp_id == image_id) { | |
368 res_id = kResourceImageMap[i].res_id; | |
369 break; | |
370 } | |
371 } | |
372 if (res_id == 0) | |
373 return 0; | |
374 | |
375 // Validate the instance. | |
376 content::PepperPluginInstance* instance = | |
377 content::PepperPluginInstance::Get(instance_id); | |
378 if (!instance) | |
379 return 0; | |
380 | |
381 gfx::ImageSkia* res_image_skia = | |
382 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(res_id); | |
383 | |
384 if (!res_image_skia) | |
385 return 0; | |
386 | |
387 return instance->CreateImage(res_image_skia, scale); | |
388 } | |
389 | |
390 PP_Resource GetResourceImage(PP_Instance instance_id, | |
391 PP_ResourceImage image_id) { | |
392 return GetResourceImageForScale(instance_id, image_id, 1.0f); | |
393 } | |
394 | |
395 PP_Var ModalPromptForPassword(PP_Instance instance_id, PP_Var message) { | |
396 content::PepperPluginInstance* instance = | |
397 content::PepperPluginInstance::Get(instance_id); | |
398 if (!instance) | |
399 return PP_MakeUndefined(); | |
400 | |
401 std::string actual_value; | |
402 scoped_refptr<ppapi::StringVar> message_string( | |
403 ppapi::StringVar::FromPPVar(message)); | |
404 | |
405 IPC::SyncMessage* msg = new ChromeViewHostMsg_PDFModalPromptForPassword( | |
406 instance->GetRenderView()->GetRoutingID(), | |
407 message_string->value(), | |
408 &actual_value); | |
409 msg->EnableMessagePumping(); | |
410 instance->GetRenderView()->Send(msg); | |
411 | |
412 return ppapi::StringVar::StringToPPVar(actual_value); | |
413 } | |
414 | |
415 PP_Bool IsOutOfProcess(PP_Instance instance_id) { return PP_FALSE; } | |
416 | |
417 void SetSelectedText(PP_Instance instance_id, const char* selected_text) { | |
418 // This function is intended for out of process PDF plugin. | |
419 } | |
420 | |
421 void SetLinkUnderCursor(PP_Instance instance_id, const char* url) { | |
422 content::PepperPluginInstance* instance = | |
423 content::PepperPluginInstance::Get(instance_id); | |
424 if (!instance) | |
425 return; | |
426 instance->SetLinkUnderCursor(url); | |
427 } | |
428 | |
429 const PPB_PDF ppb_pdf = { // | |
430 &GetLocalizedString, // | |
431 &GetResourceImage, // | |
432 &GetFontFileWithFallback, // | |
433 &GetFontTableForPrivateFontFile, // | |
434 &SearchString, // | |
435 &DidStartLoading, // | |
436 &DidStopLoading, // | |
437 &SetContentRestriction, // | |
438 &HistogramPDFPageCount, // | |
439 &UserMetricsRecordAction, // | |
440 &HasUnsupportedFeature, // | |
441 &SaveAs, // | |
442 &PPB_PDF_Impl::InvokePrintingForInstance, // | |
443 &IsFeatureEnabled, // | |
444 &GetResourceImageForScale, // | |
445 &ModalPromptForPassword, // | |
446 &IsOutOfProcess, // | |
447 &SetSelectedText, // | |
448 &SetLinkUnderCursor, // | |
449 }; | |
450 | |
451 } // namespace | |
452 | |
453 // static | |
454 const PPB_PDF* PPB_PDF_Impl::GetInterface() { return &ppb_pdf; } | |
455 | |
456 // static | |
457 void PPB_PDF_Impl::InvokePrintingForInstance(PP_Instance instance_id) { | |
458 #if defined(ENABLE_FULL_PRINTING) | |
459 blink::WebElement element = GetWebElement(instance_id); | |
460 printing::PrintWebViewHelper* helper = GetPrintWebViewHelper(element); | |
461 if (helper) | |
462 helper->PrintNode(element); | |
463 #endif // ENABLE_FULL_PRINTING | |
464 } | |
OLD | NEW |