Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: chrome/renderer/chrome_ppb_pdf_impl.cc

Issue 10173029: Add a PPB_Flash_Print interface and implement in Chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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/chrome_ppb_pdf_impl.h"
6
7 #include "base/metrics/histogram.h"
8 #include "base/utf_string_conversions.h"
9 #include "build/build_config.h"
10 #include "chrome/common/render_messages.h"
11 #include "chrome/renderer/print_web_view_helper.h"
12 #include "content/public/common/child_process_sandbox_support_linux.h"
13 #include "content/public/common/content_client.h"
14 #include "content/public/renderer/render_thread.h"
15 #include "content/public/renderer/render_view.h"
16 #include "grit/webkit_resources.h"
17 #include "grit/webkit_strings.h"
18 #include "ppapi/c/pp_resource.h"
19 #include "ppapi/c/private/ppb_pdf.h"
20 #include "ppapi/shared_impl/resource.h"
21 #include "ppapi/shared_impl/resource_tracker.h"
22 #include "ppapi/shared_impl/var.h"
23 #include "skia/ext/platform_canvas.h"
24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
30 #include "third_party/skia/include/core/SkBitmap.h"
31 #include "ui/base/l10n/l10n_util.h"
32 #include "ui/base/resource/resource_bundle.h"
33 #include "unicode/usearch.h"
34 #include "webkit/plugins/ppapi/host_globals.h"
35 #include "webkit/plugins/ppapi/plugin_delegate.h"
36 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
37 #include "webkit/plugins/ppapi/ppb_image_data_impl.h"
38
39 using ppapi::PpapiGlobals;
40 using webkit::ppapi::HostGlobals;
41 using webkit::ppapi::PluginInstance;
42 using WebKit::WebElement;
43 using WebKit::WebView;
44 using content::RenderThread;
45
46 namespace chrome {
47
48 #if defined(OS_LINUX) || defined(OS_OPENBSD)
49 class PrivateFontFile : public ppapi::Resource {
50 public:
51 PrivateFontFile(PP_Instance instance, int fd)
52 : Resource(ppapi::OBJECT_IS_IMPL, instance),
53 fd_(fd) {
54 }
55 virtual ~PrivateFontFile() {
56 }
57
58 bool GetFontTable(uint32_t table,
59 void* output,
60 uint32_t* output_length) {
61 size_t temp_size = static_cast<size_t>(*output_length);
62 bool rv = content::GetFontTable(
63 fd_, table, static_cast<uint8_t*>(output), &temp_size);
64 *output_length = static_cast<uint32_t>(temp_size);
65 return rv;
66 }
67
68 private:
69 int fd_;
70 };
71 #endif
72
73 struct ResourceImageInfo {
74 PP_ResourceImage pp_id;
75 int res_id;
76 };
77
78 static const ResourceImageInfo kResourceImageMap[] = {
79 { PP_RESOURCEIMAGE_PDF_BUTTON_FTP, IDR_PDF_BUTTON_FTP },
80 { PP_RESOURCEIMAGE_PDF_BUTTON_FTP_HOVER, IDR_PDF_BUTTON_FTP_HOVER },
81 { PP_RESOURCEIMAGE_PDF_BUTTON_FTP_PRESSED, IDR_PDF_BUTTON_FTP_PRESSED },
82 { PP_RESOURCEIMAGE_PDF_BUTTON_FTW, IDR_PDF_BUTTON_FTW },
83 { PP_RESOURCEIMAGE_PDF_BUTTON_FTW_HOVER, IDR_PDF_BUTTON_FTW_HOVER },
84 { PP_RESOURCEIMAGE_PDF_BUTTON_FTW_PRESSED, IDR_PDF_BUTTON_FTW_PRESSED },
85 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END, IDR_PDF_BUTTON_ZOOMIN_END },
86 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END_HOVER,
87 IDR_PDF_BUTTON_ZOOMIN_END_HOVER },
88 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END_PRESSED,
89 IDR_PDF_BUTTON_ZOOMIN_END_PRESSED },
90 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN, IDR_PDF_BUTTON_ZOOMIN },
91 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_HOVER, IDR_PDF_BUTTON_ZOOMIN_HOVER },
92 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_PRESSED, IDR_PDF_BUTTON_ZOOMIN_PRESSED },
93 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT, IDR_PDF_BUTTON_ZOOMOUT },
94 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_HOVER, IDR_PDF_BUTTON_ZOOMOUT_HOVER },
95 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_PRESSED,
96 IDR_PDF_BUTTON_ZOOMOUT_PRESSED },
97 { PP_RESOURCEIMAGE_PDF_BUTTON_SAVE, IDR_PDF_BUTTON_SAVE },
98 { PP_RESOURCEIMAGE_PDF_BUTTON_SAVE_HOVER, IDR_PDF_BUTTON_SAVE_HOVER },
99 { PP_RESOURCEIMAGE_PDF_BUTTON_SAVE_PRESSED, IDR_PDF_BUTTON_SAVE_PRESSED },
100 { PP_RESOURCEIMAGE_PDF_BUTTON_PRINT, IDR_PDF_BUTTON_PRINT },
101 { PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_HOVER, IDR_PDF_BUTTON_PRINT_HOVER },
102 { PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_PRESSED, IDR_PDF_BUTTON_PRINT_PRESSED },
103 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_0, IDR_PDF_THUMBNAIL_0 },
104 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_1, IDR_PDF_THUMBNAIL_1 },
105 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_2, IDR_PDF_THUMBNAIL_2 },
106 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_3, IDR_PDF_THUMBNAIL_3 },
107 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_4, IDR_PDF_THUMBNAIL_4 },
108 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_5, IDR_PDF_THUMBNAIL_5 },
109 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_6, IDR_PDF_THUMBNAIL_6 },
110 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_7, IDR_PDF_THUMBNAIL_7 },
111 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_8, IDR_PDF_THUMBNAIL_8 },
112 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_9, IDR_PDF_THUMBNAIL_9 },
113 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_NUM_BACKGROUND,
114 IDR_PDF_THUMBNAIL_NUM_BACKGROUND },
115 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_0, IDR_PDF_PROGRESS_BAR_0 },
116 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_1, IDR_PDF_PROGRESS_BAR_1 },
117 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_2, IDR_PDF_PROGRESS_BAR_2 },
118 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_3, IDR_PDF_PROGRESS_BAR_3 },
119 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_4, IDR_PDF_PROGRESS_BAR_4 },
120 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_5, IDR_PDF_PROGRESS_BAR_5 },
121 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_6, IDR_PDF_PROGRESS_BAR_6 },
122 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_7, IDR_PDF_PROGRESS_BAR_7 },
123 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_8, IDR_PDF_PROGRESS_BAR_8 },
124 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_BACKGROUND,
125 IDR_PDF_PROGRESS_BAR_BACKGROUND },
126 { PP_RESOURCEIMAGE_PDF_PAGE_INDICATOR_BACKGROUND,
127 IDR_PDF_PAGE_INDICATOR_BACKGROUND },
128 { PP_RESOURCEIMAGE_PDF_PAGE_DROPSHADOW, IDR_PDF_PAGE_DROPSHADOW },
129 { PP_RESOURCEIMAGE_PDF_PAN_SCROLL_ICON, IDR_PAN_SCROLL_ICON },
130 };
131
132 PP_Var GetLocalizedString(PP_Instance instance_id,
133 PP_ResourceString string_id) {
134 PluginInstance* instance =
135 content::GetHostGlobals()->GetInstance(instance_id);
136 if (!instance)
137 return PP_MakeUndefined();
138
139 std::string rv;
140 if (string_id == PP_RESOURCESTRING_PDFGETPASSWORD) {
141 rv = UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_NEED_PASSWORD));
142 } else if (string_id == PP_RESOURCESTRING_PDFLOADING) {
143 rv = UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_PAGE_LOADING));
144 } else if (string_id == PP_RESOURCESTRING_PDFLOAD_FAILED) {
145 rv = UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_PAGE_LOAD_FAILED));
146 } else if (string_id == PP_RESOURCESTRING_PDFPROGRESSLOADING) {
147 rv = UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_PROGRESS_LOADING));
148 } else {
149 NOTREACHED();
150 }
151
152 return ppapi::StringVar::StringToPPVar(rv);
153 }
154
155 PP_Resource GetResourceImage(PP_Instance instance_id,
156 PP_ResourceImage image_id) {
157 int res_id = 0;
158 for (size_t i = 0; i < arraysize(kResourceImageMap); ++i) {
159 if (kResourceImageMap[i].pp_id == image_id) {
160 res_id = kResourceImageMap[i].res_id;
161 break;
162 }
163 }
164 if (res_id == 0)
165 return 0;
166
167 SkBitmap* res_bitmap =
168 ResourceBundle::GetSharedInstance().GetBitmapNamed(res_id);
169
170 // Validate the instance.
171 if (!content::GetHostGlobals()->GetInstance(instance_id))
172 return 0;
173 scoped_refptr<webkit::ppapi::PPB_ImageData_Impl> image_data(
174 new webkit::ppapi::PPB_ImageData_Impl(instance_id));
175 if (!image_data->Init(
176 webkit::ppapi::PPB_ImageData_Impl::GetNativeImageDataFormat(),
177 res_bitmap->width(), res_bitmap->height(), false)) {
178 return 0;
179 }
180
181 webkit::ppapi::ImageDataAutoMapper mapper(image_data);
182 if (!mapper.is_valid())
183 return 0;
184
185 skia::PlatformCanvas* canvas = image_data->GetPlatformCanvas();
186 // Note: Do not skBitmap::copyTo the canvas bitmap directly because it will
187 // ignore the allocated pixels in shared memory and re-allocate a new buffer.
188 canvas->writePixels(*res_bitmap, 0, 0);
189
190 return image_data->GetReference();
191 }
192
193 PP_Resource GetFontFileWithFallback(
194 PP_Instance instance_id,
195 const PP_FontDescription_Dev* description,
196 PP_PrivateFontCharset charset) {
197 #if defined(OS_LINUX) || defined(OS_OPENBSD)
198 // Validate the instance before using it below.
199 if (!content::GetHostGlobals()->GetInstance(instance_id))
200 return 0;
201
202 scoped_refptr<ppapi::StringVar> face_name(ppapi::StringVar::FromPPVar(
203 description->face));
204 if (!face_name)
205 return 0;
206
207 int fd = content::MatchFontWithFallback(
208 face_name->value().c_str(),
209 description->weight >= PP_FONTWEIGHT_BOLD,
210 description->italic,
211 charset);
212 if (fd == -1)
213 return 0;
214
215 scoped_refptr<PrivateFontFile> font(new PrivateFontFile(instance_id, fd));
216
217 return font->GetReference();
218 #else
219 // For trusted PPAPI plugins, this is only needed in Linux since font loading
220 // on Windows and Mac works through the renderer sandbox.
221 return 0;
222 #endif
223 }
224
225 bool GetFontTableForPrivateFontFile(PP_Resource font_file,
226 uint32_t table,
227 void* output,
228 uint32_t* output_length) {
229 #if defined(OS_LINUX) || defined(OS_OPENBSD)
230 ppapi::Resource* resource =
231 PpapiGlobals::Get()->GetResourceTracker()->GetResource(font_file);
232 if (!resource)
233 return false;
234
235 PrivateFontFile* font = static_cast<PrivateFontFile*>(resource);
236 return font->GetFontTable(table, output, output_length);
237 #else
238 return false;
239 #endif
240 }
241
242 void SearchString(PP_Instance instance,
243 const unsigned short* input_string,
244 const unsigned short* input_term,
245 bool case_sensitive,
246 PP_PrivateFindResult** results,
247 int* count) {
248 const char16* string = reinterpret_cast<const char16*>(input_string);
249 const char16* term = reinterpret_cast<const char16*>(input_term);
250
251 UErrorCode status = U_ZERO_ERROR;
252 UStringSearch* searcher = usearch_open(
253 term, -1, string, -1, RenderThread::Get()->GetLocale().c_str(), 0,
254 &status);
255 DCHECK(status == U_ZERO_ERROR || status == U_USING_FALLBACK_WARNING ||
256 status == U_USING_DEFAULT_WARNING);
257 UCollationStrength strength = case_sensitive ? UCOL_TERTIARY : UCOL_PRIMARY;
258
259 UCollator* collator = usearch_getCollator(searcher);
260 if (ucol_getStrength(collator) != strength) {
261 ucol_setStrength(collator, strength);
262 usearch_reset(searcher);
263 }
264
265 status = U_ZERO_ERROR;
266 int match_start = usearch_first(searcher, &status);
267 DCHECK(status == U_ZERO_ERROR);
268
269 std::vector<PP_PrivateFindResult> pp_results;
270 while (match_start != USEARCH_DONE) {
271 size_t matched_length = usearch_getMatchedLength(searcher);
272 PP_PrivateFindResult result;
273 result.start_index = match_start;
274 result.length = matched_length;
275 pp_results.push_back(result);
276 match_start = usearch_next(searcher, &status);
277 DCHECK(status == U_ZERO_ERROR);
278 }
279
280 *count = pp_results.size();
281 if (*count) {
282 *results = reinterpret_cast<PP_PrivateFindResult*>(
283 malloc(*count * sizeof(PP_PrivateFindResult)));
284 memcpy(*results, &pp_results[0], *count * sizeof(PP_PrivateFindResult));
285 } else {
286 *results = NULL;
287 }
288
289 usearch_close(searcher);
290 }
291
292 void DidStartLoading(PP_Instance instance_id) {
293 PluginInstance* instance = content::GetHostGlobals()->GetInstance(instance_id) ;
294 if (!instance)
295 return;
296 instance->delegate()->DidStartLoading();
297 }
298
299 void DidStopLoading(PP_Instance instance_id) {
300 PluginInstance* instance =
301 content::GetHostGlobals()->GetInstance(instance_id);
302 if (!instance)
303 return;
304 instance->delegate()->DidStopLoading();
305 }
306
307 void SetContentRestriction(PP_Instance instance_id, int restrictions) {
308 PluginInstance* instance =
309 content::GetHostGlobals()->GetInstance(instance_id);
310 if (!instance)
311 return;
312 instance->delegate()->SetContentRestriction(restrictions);
313 }
314
315 void HistogramPDFPageCount(int count) {
316 UMA_HISTOGRAM_COUNTS_10000("PDF.PageCount", count);
317 }
318
319 void UserMetricsRecordAction(PP_Var action) {
320 scoped_refptr<ppapi::StringVar> action_str(
321 ppapi::StringVar::FromPPVar(action));
322 if (action_str)
323 RenderThread::Get()->RecordUserMetrics(action_str->value());
324 }
325
326 void HasUnsupportedFeature(PP_Instance instance_id) {
327 PluginInstance* instance =
328 content::GetHostGlobals()->GetInstance(instance_id);
329 if (!instance)
330 return;
331
332 // Only want to show an info bar if the pdf is the whole tab.
333 if (!instance->IsFullPagePlugin())
334 return;
335
336 WebView* view = instance->container()->element().document().frame()->view();
337 content::RenderView* render_view = content::RenderView::FromWebView(view);
338 render_view->Send(new ChromeViewHostMsg_PDFHasUnsupportedFeature(
339 render_view->GetRoutingID()));
340 }
341
342 void SaveAs(PP_Instance instance_id) {
343 PluginInstance* instance =
344 content::GetHostGlobals()->GetInstance(instance_id);
345 if (!instance)
346 return;
347 instance->delegate()->SaveURLAs(instance->plugin_url());
348 }
349
350 void Print(PP_Instance instance_id) {
351 PluginInstance* instance = HostGlobals::Get()->GetInstance(instance_id);
352 if (!instance)
353 return;
354
355 WebElement element = instance->container()->element();
356 WebView* view = element.document().frame()->view();
357 content::RenderView* render_view = content::RenderView::FromWebView(view);
358
359 PrintWebViewHelper* print_view_helper = PrintWebViewHelper::Get(render_view);
360 if (print_view_helper) {
361 print_view_helper->PrintNode(element);
362 }
363 }
364
365 const PPB_PDF ppb_pdf = {
366 &GetLocalizedString,
367 &GetResourceImage,
368 &GetFontFileWithFallback,
369 &GetFontTableForPrivateFontFile,
370 &SearchString,
371 &DidStartLoading,
372 &DidStopLoading,
373 &SetContentRestriction,
374 &HistogramPDFPageCount,
375 &UserMetricsRecordAction,
376 &HasUnsupportedFeature,
377 &SaveAs,
378 &Print
379 };
380
381 // static
382 const PPB_PDF* PPB_PDF_Impl::GetInterface() {
383 return &ppb_pdf;
384 }
385
386 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698