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/pepper_pdf_host.h" | |
6 | |
7 #include "base/utf_string_conversions.h" | |
8 #include "chrome/common/render_messages.h" | |
9 #include "chrome/renderer/printing/print_web_view_helper.h" | |
10 #include "content/public/renderer/render_thread.h" | |
11 #include "content/public/renderer/render_view.h" | |
12 #include "content/public/renderer/renderer_ppapi_host.h" | |
13 #include "grit/webkit_resources.h" | |
14 #include "grit/webkit_strings.h" | |
15 #include "ppapi/host/dispatch_host_message.h" | |
16 #include "ppapi/host/host_message_context.h" | |
17 #include "ppapi/host/ppapi_host.h" | |
18 #include "ppapi/proxy/host_dispatcher.h" | |
19 #include "ppapi/proxy/ppapi_messages.h" | |
20 #include "ppapi/proxy/ppb_image_data_proxy.h" | |
21 #include "ppapi/shared_impl/scoped_pp_resource.h" | |
22 #include "ppapi/thunk/enter.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/WebPluginContainer.h" | |
28 #include "ui/base/l10n/l10n_util.h" | |
29 #include "ui/base/layout.h" | |
30 #include "ui/base/resource/resource_bundle.h" | |
31 #include "ui/gfx/image/image_skia.h" | |
32 #include "ui/gfx/image/image_skia_rep.h" | |
33 #include "ui/gfx/point.h" | |
34 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" | |
35 #include "webkit/plugins/ppapi/ppb_image_data_impl.h" | |
36 | |
37 using webkit::ppapi::PluginInstance; | |
38 | |
39 namespace chrome { | |
40 | |
41 namespace { | |
42 | |
43 struct ResourceImageInfo { | |
44 PP_ResourceImage pp_id; | |
45 int res_id; | |
46 }; | |
47 | |
48 static const ResourceImageInfo kResourceImageMap[] = { | |
49 { PP_RESOURCEIMAGE_PDF_BUTTON_FTP, IDR_PDF_BUTTON_FTP }, | |
50 { PP_RESOURCEIMAGE_PDF_BUTTON_FTP_HOVER, IDR_PDF_BUTTON_FTP_HOVER }, | |
51 { PP_RESOURCEIMAGE_PDF_BUTTON_FTP_PRESSED, IDR_PDF_BUTTON_FTP_PRESSED }, | |
52 { PP_RESOURCEIMAGE_PDF_BUTTON_FTW, IDR_PDF_BUTTON_FTW }, | |
53 { PP_RESOURCEIMAGE_PDF_BUTTON_FTW_HOVER, IDR_PDF_BUTTON_FTW_HOVER }, | |
54 { PP_RESOURCEIMAGE_PDF_BUTTON_FTW_PRESSED, IDR_PDF_BUTTON_FTW_PRESSED }, | |
55 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END, IDR_PDF_BUTTON_ZOOMIN_END }, | |
56 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END_HOVER, | |
57 IDR_PDF_BUTTON_ZOOMIN_END_HOVER }, | |
58 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END_PRESSED, | |
59 IDR_PDF_BUTTON_ZOOMIN_END_PRESSED }, | |
60 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN, IDR_PDF_BUTTON_ZOOMIN }, | |
61 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_HOVER, IDR_PDF_BUTTON_ZOOMIN_HOVER }, | |
62 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_PRESSED, IDR_PDF_BUTTON_ZOOMIN_PRESSED }, | |
63 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT, IDR_PDF_BUTTON_ZOOMOUT }, | |
64 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_HOVER, IDR_PDF_BUTTON_ZOOMOUT_HOVER }, | |
65 { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_PRESSED, | |
66 IDR_PDF_BUTTON_ZOOMOUT_PRESSED }, | |
67 { PP_RESOURCEIMAGE_PDF_BUTTON_SAVE, IDR_PDF_BUTTON_SAVE }, | |
68 { PP_RESOURCEIMAGE_PDF_BUTTON_SAVE_HOVER, IDR_PDF_BUTTON_SAVE_HOVER }, | |
69 { PP_RESOURCEIMAGE_PDF_BUTTON_SAVE_PRESSED, IDR_PDF_BUTTON_SAVE_PRESSED }, | |
70 { PP_RESOURCEIMAGE_PDF_BUTTON_PRINT, IDR_PDF_BUTTON_PRINT }, | |
71 { PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_HOVER, IDR_PDF_BUTTON_PRINT_HOVER }, | |
72 { PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_PRESSED, IDR_PDF_BUTTON_PRINT_PRESSED }, | |
73 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_0, IDR_PDF_THUMBNAIL_0 }, | |
74 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_1, IDR_PDF_THUMBNAIL_1 }, | |
75 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_2, IDR_PDF_THUMBNAIL_2 }, | |
76 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_3, IDR_PDF_THUMBNAIL_3 }, | |
77 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_4, IDR_PDF_THUMBNAIL_4 }, | |
78 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_5, IDR_PDF_THUMBNAIL_5 }, | |
79 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_6, IDR_PDF_THUMBNAIL_6 }, | |
80 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_7, IDR_PDF_THUMBNAIL_7 }, | |
81 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_8, IDR_PDF_THUMBNAIL_8 }, | |
82 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_9, IDR_PDF_THUMBNAIL_9 }, | |
83 { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_NUM_BACKGROUND, | |
84 IDR_PDF_THUMBNAIL_NUM_BACKGROUND }, | |
85 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_0, IDR_PDF_PROGRESS_BAR_0 }, | |
86 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_1, IDR_PDF_PROGRESS_BAR_1 }, | |
87 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_2, IDR_PDF_PROGRESS_BAR_2 }, | |
88 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_3, IDR_PDF_PROGRESS_BAR_3 }, | |
89 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_4, IDR_PDF_PROGRESS_BAR_4 }, | |
90 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_5, IDR_PDF_PROGRESS_BAR_5 }, | |
91 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_6, IDR_PDF_PROGRESS_BAR_6 }, | |
92 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_7, IDR_PDF_PROGRESS_BAR_7 }, | |
93 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_8, IDR_PDF_PROGRESS_BAR_8 }, | |
94 { PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_BACKGROUND, | |
95 IDR_PDF_PROGRESS_BAR_BACKGROUND }, | |
96 { PP_RESOURCEIMAGE_PDF_PAGE_INDICATOR_BACKGROUND, | |
97 IDR_PDF_PAGE_INDICATOR_BACKGROUND }, | |
98 { PP_RESOURCEIMAGE_PDF_PAGE_DROPSHADOW, IDR_PDF_PAGE_DROPSHADOW }, | |
99 { PP_RESOURCEIMAGE_PDF_PAN_SCROLL_ICON, IDR_PAN_SCROLL_ICON }, | |
100 }; | |
101 | |
102 // Valid strings for user metrics actions. | |
103 static const char* kValidUserMetricsActions[] = { | |
104 "PDF.PrintPage", | |
105 "PDF.ZoomFromBrowser", | |
106 "PDF.FitToPageButton", | |
107 "PDF.FitToWidthButton", | |
108 "PDF.ZoomOutButton", | |
109 "PDF.ZoomInButton", | |
110 "PDF.SaveButton", | |
111 "PDF.PrintButton", | |
112 "PDF.LoadSuccess", | |
113 "PDF.LoadFailure", | |
114 "PDF.PreviewDocumentLoadFailure", | |
115 }; | |
116 | |
117 } // namespace | |
118 | |
119 PepperPDFHost::PepperPDFHost( | |
120 content::RendererPpapiHost* host, | |
121 PP_Instance instance, | |
122 PP_Resource resource) | |
123 : ppapi::host::ResourceHost(host->GetPpapiHost(), instance, resource), | |
124 host_(host) { | |
125 } | |
126 | |
127 PepperPDFHost::~PepperPDFHost() { | |
128 } | |
129 | |
130 int32_t PepperPDFHost::OnResourceMessageReceived( | |
131 const IPC::Message& msg, | |
132 ppapi::host::HostMessageContext* context) { | |
133 IPC_BEGIN_MESSAGE_MAP(PepperPDFHost, msg) | |
134 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_GetLocalizedString, | |
135 OnHostMsgGetLocalizedString) | |
136 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_DidStartLoading, | |
137 OnHostMsgDidStartLoading) | |
138 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_DidStopLoading, | |
139 OnHostMsgDidStopLoading) | |
140 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_UserMetricsRecordAction, | |
141 OnHostMsgUserMetricsRecordAction) | |
142 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_HasUnsupportedFeature, | |
143 OnHostMsgHasUnsupportedFeature) | |
144 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_Print, | |
145 OnHostMsgPrint) | |
146 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_SaveAs, | |
147 OnHostMsgSaveAs) | |
148 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_GetResourceImage, | |
149 OnHostMsgGetResourceImage) | |
150 IPC_END_MESSAGE_MAP() | |
151 return PP_ERROR_FAILED; | |
152 } | |
153 | |
154 int32_t PepperPDFHost::OnHostMsgGetLocalizedString( | |
155 ppapi::host::HostMessageContext* context, | |
156 int string_id) { | |
157 PP_ResourceString resource_string_id = | |
158 static_cast<PP_ResourceString>(string_id); | |
yzshen1
2013/04/03 18:32:39
If we pass |string_id| as int to be 'safe', then w
raymes
2013/04/03 23:18:21
I just changed it to send the enum value.
yzshen1
2013/04/04 01:30:07
There was a discussion about passing enum values o
| |
159 std::string rv; | |
160 if (resource_string_id == PP_RESOURCESTRING_PDFGETPASSWORD) { | |
161 rv = UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_NEED_PASSWORD)); | |
162 } else if (resource_string_id == PP_RESOURCESTRING_PDFLOADING) { | |
163 rv = UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_PAGE_LOADING)); | |
164 } else if (resource_string_id == PP_RESOURCESTRING_PDFLOAD_FAILED) { | |
165 rv = UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_PAGE_LOAD_FAILED)); | |
166 } else if (resource_string_id == PP_RESOURCESTRING_PDFPROGRESSLOADING) { | |
167 rv = UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_PROGRESS_LOADING)); | |
168 } else { | |
169 NOTREACHED(); | |
170 return PP_ERROR_FAILED; | |
171 } | |
172 | |
173 context->reply_msg = PpapiPluginMsg_PDF_GetLocalizedStringReply(rv); | |
174 return PP_OK; | |
175 } | |
176 | |
177 int32_t PepperPDFHost::OnHostMsgDidStartLoading( | |
178 ppapi::host::HostMessageContext* context) { | |
179 PluginInstance* instance = host_->GetPluginInstance(pp_instance()); | |
180 if (!instance) | |
181 return PP_ERROR_FAILED; | |
182 instance->delegate()->DidStartLoading(); | |
183 return PP_OK; | |
184 } | |
185 | |
186 int32_t PepperPDFHost::OnHostMsgDidStopLoading( | |
187 ppapi::host::HostMessageContext* context) { | |
188 PluginInstance* instance = host_->GetPluginInstance(pp_instance()); | |
189 if (!instance) | |
190 return PP_ERROR_FAILED; | |
191 instance->delegate()->DidStopLoading(); | |
192 return PP_OK; | |
193 } | |
194 | |
195 int32_t PepperPDFHost::OnHostMsgSetContentRestriction( | |
196 ppapi::host::HostMessageContext* context, int restrictions) { | |
197 PluginInstance* instance = host_->GetPluginInstance(pp_instance()); | |
198 if (!instance) | |
199 return PP_ERROR_FAILED; | |
200 instance->delegate()->SetContentRestriction(restrictions); | |
201 return PP_OK; | |
202 } | |
203 | |
204 int32_t PepperPDFHost::OnHostMsgUserMetricsRecordAction( | |
205 ppapi::host::HostMessageContext* context, | |
206 std::string action) { | |
207 bool valid = false; | |
208 for (size_t i = 0; i < arraysize(kResourceImageMap); ++i) { | |
209 if (action == kValidUserMetricsActions[i]) { | |
210 valid = true; | |
211 break; | |
212 } | |
213 } | |
214 if (!valid) { | |
215 NOTREACHED(); | |
216 return PP_ERROR_FAILED; | |
217 } | |
218 content::RenderThread::Get()->RecordUserMetrics(action); | |
219 return PP_OK; | |
220 } | |
221 | |
222 int32_t PepperPDFHost::OnHostMsgHasUnsupportedFeature( | |
223 ppapi::host::HostMessageContext* context) { | |
224 PluginInstance* instance = host_->GetPluginInstance(pp_instance()); | |
225 if (!instance) | |
226 return PP_ERROR_FAILED; | |
227 | |
228 // Only want to show an info bar if the pdf is the whole tab. | |
229 if (!instance->IsFullPagePlugin()) | |
230 return PP_OK; | |
231 | |
232 WebKit::WebView* view = | |
233 instance->container()->element().document().frame()->view(); | |
234 content::RenderView* render_view = content::RenderView::FromWebView(view); | |
235 render_view->Send(new ChromeViewHostMsg_PDFHasUnsupportedFeature( | |
236 render_view->GetRoutingID())); | |
237 return PP_OK; | |
238 } | |
239 | |
240 int32_t PepperPDFHost::OnHostMsgPrint( | |
241 ppapi::host::HostMessageContext* context) { | |
242 #if defined(ENABLE_PRINTING) | |
243 PluginInstance* instance = host_->GetPluginInstance(pp_instance()); | |
244 if (!instance) | |
245 return PP_ERROR_FAILED; | |
246 | |
247 WebKit::WebElement element = instance->container()->element(); | |
248 WebKit::WebView* view = element.document().frame()->view(); | |
249 content::RenderView* render_view = content::RenderView::FromWebView(view); | |
250 | |
251 using printing::PrintWebViewHelper; | |
252 PrintWebViewHelper* print_view_helper = PrintWebViewHelper::Get(render_view); | |
253 if (print_view_helper) { | |
254 print_view_helper->PrintNode(element); | |
255 return PP_OK; | |
256 } | |
257 #endif | |
258 return PP_ERROR_FAILED; | |
259 } | |
260 | |
261 int32_t PepperPDFHost::OnHostMsgSaveAs( | |
262 ppapi::host::HostMessageContext* context) { | |
263 PluginInstance* instance = host_->GetPluginInstance(pp_instance()); | |
264 if (!instance) | |
265 return PP_ERROR_FAILED; | |
266 instance->delegate()->SaveURLAs(instance->plugin_url()); | |
267 return PP_OK; | |
268 } | |
269 | |
270 int32_t PepperPDFHost::OnHostMsgGetResourceImage( | |
271 ppapi::host::HostMessageContext* context, | |
272 int image_id, | |
273 float scale) { | |
274 int res_id = 0; | |
275 for (size_t i = 0; i < arraysize(kResourceImageMap); ++i) { | |
276 if (kResourceImageMap[i].pp_id == | |
277 static_cast<PP_ResourceImage>(image_id)) { | |
278 res_id = kResourceImageMap[i].res_id; | |
279 break; | |
280 } | |
281 } | |
282 if (res_id == 0) | |
283 return PP_ERROR_FAILED; | |
284 | |
285 ui::ScaleFactor scale_factor = ui::GetScaleFactorFromScale(scale); | |
286 | |
287 gfx::ImageSkia* res_image_skia = | |
288 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(res_id); | |
289 | |
290 if (!res_image_skia) | |
291 return PP_ERROR_FAILED; | |
292 | |
293 gfx::ImageSkiaRep image_skia_rep = res_image_skia->GetRepresentation( | |
294 scale_factor); | |
295 | |
296 if (image_skia_rep.is_null() || image_skia_rep.scale_factor() != scale_factor) | |
297 return PP_ERROR_FAILED; | |
298 | |
299 PP_Size pp_size; | |
300 pp_size.width = image_skia_rep.pixel_width(); | |
301 pp_size.height = image_skia_rep.pixel_height(); | |
302 | |
303 ppapi::HostResource host_resource; | |
304 std::string image_data_desc; | |
305 ppapi::proxy::ImageHandle image_handle; | |
306 uint32_t byte_count = 0; | |
307 bool success = CreateImageData( | |
308 pp_instance(), | |
309 webkit::ppapi::PPB_ImageData_Impl::GetNativeImageDataFormat(), | |
310 pp_size, | |
311 image_skia_rep.sk_bitmap(), | |
312 &host_resource, | |
313 &image_data_desc, | |
314 &image_handle, | |
315 &byte_count); | |
316 ppapi::ScopedPPResource image_data_resource( | |
317 ppapi::ScopedPPResource::PassRef(), host_resource.host_resource()); | |
318 if (!success) | |
319 return PP_ERROR_FAILED; | |
320 | |
321 ppapi::host::ReplyMessageContext reply_context = | |
322 context->MakeReplyMessageContext(); | |
323 // This mess of #defines is needed to translate between ImageHandles and | |
324 // SerializedHandles. This is something that should be addressed with a | |
325 // refactoring of PPB_ImageData. | |
326 #if defined(OS_WIN) | |
327 ppapi::proxy::SerializedHandle serialized_handle; | |
328 PpapiPluginMsg_PDF_GetResourceImageReply reply_msg(host_resource, | |
329 image_data_desc, | |
330 0); | |
331 ppapi::proxy::HostDispatcher* dispatcher = | |
332 ppapi::proxy::HostDispatcher::GetForInstance(pp_instance()); | |
333 if (!dispatcher) | |
334 return PP_ERROR_FAILED; | |
335 serialized_handle.set_shmem( | |
336 dispatcher->ShareHandleWithRemote(image_handle, false), byte_count); | |
337 reply_context.params.AppendHandle(serialized_handle); | |
338 #elif defined(OS_MACOSX) | |
339 ppapi::proxy::SerializedHandle serialized_handle; | |
340 PpapiPluginMsg_PDF_GetResourceImageReply reply_msg(host_resource, | |
341 image_data_desc, | |
342 0); | |
343 serialized_handle.set_shmem(image_handle, byte_count); | |
344 reply_context.params.AppendHandle(serialized_handle); | |
345 #elif defined(OS_LINUX) | |
346 // For linux, we pass the SysV shared memory key in the message. | |
347 PpapiPluginMsg_PDF_GetResourceImageReply reply_msg(host_resource, | |
348 image_data_desc, | |
349 image_handle); | |
350 #else | |
351 #error Not implemented. | |
352 #endif | |
353 | |
354 SendReply(reply_context, reply_msg); | |
355 | |
356 // Keep a reference to the resource only if the function succeeds. | |
357 image_data_resource.Release(); | |
358 | |
359 return PP_OK_COMPLETIONPENDING; | |
360 } | |
361 | |
362 // TODO(raymes): This function is mainly copied from ppb_image_data_proxy.cc. | |
363 // It's a mess and needs to be fixed in several ways but this is better done | |
364 // when we refactor PPB_ImageData. On success, the serialized handle will be | |
365 // non-null. | |
366 bool PepperPDFHost::CreateImageData( | |
367 PP_Instance instance, | |
368 int32_t format, | |
yzshen1
2013/04/03 18:32:39
Why not making it PP_ImageDataFormat directly?
raymes
2013/04/03 23:18:21
Done.
| |
369 const PP_Size& size, | |
370 const SkBitmap& pixels_to_write, | |
371 ppapi::HostResource* result, | |
372 std::string* out_image_data_desc, | |
373 ppapi::proxy::ImageHandle* out_image_handle, | |
374 uint32_t* out_byte_count) { | |
375 // Create the resource. | |
376 ppapi::thunk::EnterResourceCreation enter(instance); | |
377 if (enter.failed()) | |
378 return false; | |
379 | |
380 PP_Resource resource = enter.functions()->CreateImageData( | |
381 instance, static_cast<PP_ImageDataFormat>(format), size, PP_FALSE); | |
382 if (!resource) | |
383 return false; | |
384 result->SetHostResource(instance, resource); | |
385 | |
386 // Write the image to the resource shared memory. | |
387 ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API> | |
388 enter_resource(resource, false); | |
389 if (enter_resource.failed()) | |
390 return false; | |
391 | |
392 webkit::ppapi::PPB_ImageData_Impl* image_data = | |
393 static_cast<webkit::ppapi::PPB_ImageData_Impl*>(enter_resource.object()); | |
394 webkit::ppapi::ImageDataAutoMapper mapper(image_data); | |
395 if (!mapper.is_valid()) | |
396 return false; | |
397 | |
398 skia::PlatformCanvas* canvas = image_data->GetPlatformCanvas(); | |
399 // Note: Do not skBitmap::copyTo the canvas bitmap directly because it will | |
400 // ignore the allocated pixels in shared memory and re-allocate a new buffer. | |
401 canvas->writePixels(pixels_to_write, 0, 0); | |
402 | |
403 // Get the image description, it's just serialized as a string. | |
404 PP_ImageDataDesc desc; | |
405 if (enter_resource.object()->Describe(&desc) == PP_TRUE) { | |
406 out_image_data_desc->resize(sizeof(PP_ImageDataDesc)); | |
407 memcpy(&(*out_image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc)); | |
408 } else { | |
409 return false; | |
410 } | |
411 | |
412 // Get the shared memory handle. | |
413 int32_t handle = 0; | |
414 if (enter_resource.object()->GetSharedMemory( | |
415 &handle, out_byte_count) != PP_OK) { | |
416 return false; | |
417 } | |
418 | |
419 *out_image_handle = ppapi::proxy::ImageData::HandleFromInt(handle); | |
420 return true; | |
421 } | |
422 | |
423 } // namespace chrome | |
OLD | NEW |