Index: webkit/glue/plugins/pepper_plugin_instance.cc |
=================================================================== |
--- webkit/glue/plugins/pepper_plugin_instance.cc (revision 69381) |
+++ webkit/glue/plugins/pepper_plugin_instance.cc (working copy) |
@@ -1,1179 +0,0 @@ |
-// Copyright (c) 2010 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "webkit/glue/plugins/pepper_plugin_instance.h" |
- |
-#include "base/logging.h" |
-#include "base/metrics/histogram.h" |
-#if defined(OS_MACOSX) |
-#include "base/mac_util.h" |
-#include "base/mac/scoped_cftyperef.h" |
-#endif |
-#include "base/scoped_ptr.h" |
-#include "base/utf_string_conversions.h" |
-#include "gfx/rect.h" |
-#if defined(OS_WIN) |
-#include "gfx/codec/jpeg_codec.h" |
-#include "gfx/gdi_util.h" |
-#endif |
-#include "gfx/skia_util.h" |
-#include "ppapi/c/dev/ppb_find_dev.h" |
-#include "ppapi/c/dev/ppb_fullscreen_dev.h" |
-#include "ppapi/c/dev/ppb_zoom_dev.h" |
-#include "ppapi/c/dev/ppp_find_dev.h" |
-#include "ppapi/c/dev/ppp_selection_dev.h" |
-#include "ppapi/c/dev/ppp_zoom_dev.h" |
-#include "ppapi/c/pp_input_event.h" |
-#include "ppapi/c/pp_instance.h" |
-#include "ppapi/c/pp_rect.h" |
-#include "ppapi/c/pp_resource.h" |
-#include "ppapi/c/pp_var.h" |
-#include "ppapi/c/ppb_core.h" |
-#include "ppapi/c/ppb_instance.h" |
-#include "ppapi/c/ppp_instance.h" |
-#include "printing/native_metafile.h" |
-#include "printing/units.h" |
-#include "skia/ext/vector_platform_device.h" |
-#include "skia/ext/platform_canvas.h" |
-#include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" |
-#include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h" |
-#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" |
-#include "third_party/WebKit/WebKit/chromium/public/WebElement.h" |
-#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" |
-#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" |
-#include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h" |
-#include "third_party/WebKit/WebKit/chromium/public/WebRect.h" |
-#include "third_party/WebKit/WebKit/chromium/public/WebString.h" |
-#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" |
-#include "third_party/WebKit/WebKit/chromium/public/WebView.h" |
-#include "webkit/glue/plugins/pepper_buffer.h" |
-#include "webkit/glue/plugins/pepper_common.h" |
-#include "webkit/glue/plugins/pepper_graphics_2d.h" |
-#include "webkit/glue/plugins/pepper_graphics_3d.h" |
-#include "webkit/glue/plugins/pepper_event_conversion.h" |
-#include "webkit/glue/plugins/pepper_fullscreen_container.h" |
-#include "webkit/glue/plugins/pepper_image_data.h" |
-#include "webkit/glue/plugins/pepper_plugin_delegate.h" |
-#include "webkit/glue/plugins/pepper_plugin_module.h" |
-#include "webkit/glue/plugins/pepper_string.h" |
-#include "webkit/glue/plugins/pepper_url_loader.h" |
-#include "webkit/glue/plugins/pepper_var.h" |
-#include "webkit/glue/plugins/ppp_private.h" |
- |
-using WebKit::WebBindings; |
-using WebKit::WebCanvas; |
-using WebKit::WebCursorInfo; |
-using WebKit::WebDocument; |
-using WebKit::WebFrame; |
-using WebKit::WebInputEvent; |
-using WebKit::WebPluginContainer; |
-using WebKit::WebString; |
-using WebKit::WebURLRequest; |
-using WebKit::WebView; |
- |
-namespace pepper { |
- |
-#if defined(OS_WIN) |
-// Exported by pdf.dll |
-typedef bool (*RenderPDFPageToDCProc)( |
- const unsigned char* pdf_buffer, int buffer_size, int page_number, HDC dc, |
- int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y, |
- int bounds_width, int bounds_height, bool fit_to_bounds, |
- bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds); |
-#endif // defined(OS_WIN) |
- |
-namespace { |
- |
-#define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, np_name) \ |
- COMPILE_ASSERT(int(WebCursorInfo::webkit_name) == int(np_name), \ |
- mismatching_enums) |
- |
-COMPILE_ASSERT_MATCHING_ENUM(TypePointer, PP_CURSORTYPE_POINTER); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeCross, PP_CURSORTYPE_CROSS); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeHand, PP_CURSORTYPE_HAND); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeIBeam, PP_CURSORTYPE_IBEAM); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeWait, PP_CURSORTYPE_WAIT); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeHelp, PP_CURSORTYPE_HELP); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeEastResize, PP_CURSORTYPE_EASTRESIZE); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeNorthResize, PP_CURSORTYPE_NORTHRESIZE); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeNorthEastResize, |
- PP_CURSORTYPE_NORTHEASTRESIZE); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeNorthWestResize, |
- PP_CURSORTYPE_NORTHWESTRESIZE); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeSouthResize, PP_CURSORTYPE_SOUTHRESIZE); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeSouthEastResize, |
- PP_CURSORTYPE_SOUTHEASTRESIZE); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeSouthWestResize, |
- PP_CURSORTYPE_SOUTHWESTRESIZE); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeWestResize, PP_CURSORTYPE_WESTRESIZE); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeNorthSouthResize, |
- PP_CURSORTYPE_NORTHSOUTHRESIZE); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeEastWestResize, PP_CURSORTYPE_EASTWESTRESIZE); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeNorthEastSouthWestResize, |
- PP_CURSORTYPE_NORTHEASTSOUTHWESTRESIZE); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeNorthWestSouthEastResize, |
- PP_CURSORTYPE_NORTHWESTSOUTHEASTRESIZE); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeColumnResize, PP_CURSORTYPE_COLUMNRESIZE); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeRowResize, PP_CURSORTYPE_ROWRESIZE); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeMiddlePanning, PP_CURSORTYPE_MIDDLEPANNING); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeEastPanning, PP_CURSORTYPE_EASTPANNING); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeNorthPanning, PP_CURSORTYPE_NORTHPANNING); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeNorthEastPanning, |
- PP_CURSORTYPE_NORTHEASTPANNING); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeNorthWestPanning, |
- PP_CURSORTYPE_NORTHWESTPANNING); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeSouthPanning, PP_CURSORTYPE_SOUTHPANNING); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeSouthEastPanning, |
- PP_CURSORTYPE_SOUTHEASTPANNING); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeSouthWestPanning, |
- PP_CURSORTYPE_SOUTHWESTPANNING); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeWestPanning, PP_CURSORTYPE_WESTPANNING); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeMove, PP_CURSORTYPE_MOVE); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeVerticalText, PP_CURSORTYPE_VERTICALTEXT); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeCell, PP_CURSORTYPE_CELL); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeContextMenu, PP_CURSORTYPE_CONTEXTMENU); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeAlias, PP_CURSORTYPE_ALIAS); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeProgress, PP_CURSORTYPE_PROGRESS); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeNoDrop, PP_CURSORTYPE_NODROP); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeCopy, PP_CURSORTYPE_COPY); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeNone, PP_CURSORTYPE_NONE); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeNotAllowed, PP_CURSORTYPE_NOTALLOWED); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeZoomIn, PP_CURSORTYPE_ZOOMIN); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeZoomOut, PP_CURSORTYPE_ZOOMOUT); |
-COMPILE_ASSERT_MATCHING_ENUM(TypeCustom, PP_CURSORTYPE_CUSTOM); |
- |
-void RectToPPRect(const gfx::Rect& input, PP_Rect* output) { |
- *output = PP_MakeRectFromXYWH(input.x(), input.y(), |
- input.width(), input.height()); |
-} |
- |
-PP_Var GetWindowObject(PP_Instance instance_id) { |
- PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); |
- if (!instance) |
- return PP_MakeUndefined(); |
- return instance->GetWindowObject(); |
-} |
- |
-PP_Var GetOwnerElementObject(PP_Instance instance_id) { |
- PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); |
- if (!instance) |
- return PP_MakeUndefined(); |
- return instance->GetOwnerElementObject(); |
-} |
- |
-PP_Bool BindGraphics(PP_Instance instance_id, PP_Resource graphics_id) { |
- PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); |
- if (!instance) |
- return PP_FALSE; |
- return BoolToPPBool(instance->BindGraphics(graphics_id)); |
-} |
- |
-PP_Bool IsFullFrame(PP_Instance instance_id) { |
- PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); |
- if (!instance) |
- return PP_FALSE; |
- return BoolToPPBool(instance->full_frame()); |
-} |
- |
-PP_Var ExecuteScript(PP_Instance instance_id, |
- PP_Var script, |
- PP_Var* exception) { |
- PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); |
- if (!instance) |
- return PP_MakeUndefined(); |
- return instance->ExecuteScript(script, exception); |
-} |
- |
-const PPB_Instance ppb_instance = { |
- &GetWindowObject, |
- &GetOwnerElementObject, |
- &BindGraphics, |
- &IsFullFrame, |
- &ExecuteScript, |
-}; |
- |
-void NumberOfFindResultsChanged(PP_Instance instance_id, |
- int32_t total, |
- PP_Bool final_result) { |
- PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); |
- if (!instance) |
- return; |
- |
- DCHECK_NE(instance->find_identifier(), -1); |
- instance->delegate()->NumberOfFindResultsChanged( |
- instance->find_identifier(), total, PPBoolToBool(final_result)); |
-} |
- |
-void SelectedFindResultChanged(PP_Instance instance_id, |
- int32_t index) { |
- PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); |
- if (!instance) |
- return; |
- |
- DCHECK_NE(instance->find_identifier(), -1); |
- instance->delegate()->SelectedFindResultChanged( |
- instance->find_identifier(), index); |
-} |
- |
-const PPB_Find_Dev ppb_find = { |
- &NumberOfFindResultsChanged, |
- &SelectedFindResultChanged, |
-}; |
- |
-PP_Bool IsFullscreen(PP_Instance instance_id) { |
- PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); |
- if (!instance) |
- return PP_FALSE; |
- return BoolToPPBool(instance->IsFullscreen()); |
-} |
- |
-PP_Bool SetFullscreen(PP_Instance instance_id, PP_Bool fullscreen) { |
- PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); |
- if (!instance) |
- return PP_FALSE; |
- return BoolToPPBool(instance->SetFullscreen(PPBoolToBool(fullscreen))); |
-} |
- |
-const PPB_Fullscreen_Dev ppb_fullscreen = { |
- &IsFullscreen, |
- &SetFullscreen, |
-}; |
- |
-void ZoomChanged(PP_Instance instance_id, double factor) { |
- PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); |
- if (!instance) |
- return; |
- |
- // We only want to tell the page to change its zoom if the whole page is the |
- // PDF. If we're in an iframe, then don't do anything. |
- WebFrame* frame = instance->container()->element().document().frame(); |
- if (!frame->view()->mainFrame()->document().isPluginDocument()) |
- return; |
- |
- double zoom_level = WebView::zoomFactorToZoomLevel(factor); |
- // The conversino from zoom level to factor, and back, can introduce rounding |
- // errors. i.e. WebKit originally tells us 3.0, but by the time we tell the |
- // plugin and it tells us back, the level becomes 3.000000000004. Need to |
- // round or else otherwise if the user zooms out, it will go to 3.0 instead of |
- // 2.0. |
- int rounded = |
- static_cast<int>(zoom_level + (zoom_level > 0 ? 0.001 : -0.001)); |
- if (abs(rounded - zoom_level) < 0.001) |
- zoom_level = rounded; |
- instance->container()->zoomLevelChanged(zoom_level); |
-} |
- |
-void ZoomLimitsChanged(PP_Instance instance_id, |
- double minimum_factor, |
- double maximium_factor) { |
- if (minimum_factor > maximium_factor) { |
- NOTREACHED(); |
- return; |
- } |
- |
- PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); |
- if (!instance) |
- return; |
- instance->delegate()->ZoomLimitsChanged(minimum_factor, maximium_factor); |
-} |
- |
-const PPB_Zoom_Dev ppb_zoom = { |
- &ZoomChanged, |
- &ZoomLimitsChanged |
-}; |
- |
-} // namespace |
- |
-PluginInstance::PluginInstance(PluginDelegate* delegate, |
- PluginModule* module, |
- const PPP_Instance* instance_interface) |
- : delegate_(delegate), |
- module_(module), |
- instance_interface_(instance_interface), |
- pp_instance_(0), |
- container_(NULL), |
- full_frame_(false), |
- has_webkit_focus_(false), |
- has_content_area_focus_(false), |
- find_identifier_(-1), |
- plugin_find_interface_(NULL), |
- plugin_private_interface_(NULL), |
- plugin_selection_interface_(NULL), |
- plugin_zoom_interface_(NULL), |
-#if defined (OS_LINUX) |
- num_pages_(0), |
- pdf_output_done_(false), |
-#endif // defined (OS_LINUX) |
- plugin_print_interface_(NULL), |
- plugin_graphics_3d_interface_(NULL), |
- always_on_top_(false), |
- fullscreen_container_(NULL) { |
- pp_instance_ = ResourceTracker::Get()->AddInstance(this); |
- |
- memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); |
- DCHECK(delegate); |
- module_->InstanceCreated(this); |
- delegate_->InstanceCreated(this); |
-} |
- |
-PluginInstance::~PluginInstance() { |
- FOR_EACH_OBSERVER(Observer, observers_, InstanceDestroyed(this)); |
- |
- delegate_->InstanceDeleted(this); |
- module_->InstanceDeleted(this); |
- |
- ResourceTracker::Get()->InstanceDeleted(pp_instance_); |
-} |
- |
-// static |
-const PPB_Instance* PluginInstance::GetInterface() { |
- return &ppb_instance; |
-} |
- |
-// static |
-const PPB_Find_Dev* PluginInstance::GetFindInterface() { |
- return &ppb_find; |
-} |
- |
-// static |
-const PPB_Fullscreen_Dev* PluginInstance::GetFullscreenInterface() { |
- return &ppb_fullscreen; |
-} |
- |
-// static |
-const PPB_Zoom_Dev* PluginInstance::GetZoomInterface() { |
- return &ppb_zoom; |
-} |
- |
-void PluginInstance::AddObserver(Observer* observer) { |
- observers_.AddObserver(observer); |
-} |
- |
-void PluginInstance::RemoveObserver(Observer* observer) { |
- observers_.RemoveObserver(observer); |
-} |
- |
-void PluginInstance::Paint(WebCanvas* canvas, |
- const gfx::Rect& plugin_rect, |
- const gfx::Rect& paint_rect) { |
- if (bound_graphics_2d()) |
- bound_graphics_2d()->Paint(canvas, plugin_rect, paint_rect); |
-} |
- |
-void PluginInstance::InvalidateRect(const gfx::Rect& rect) { |
- if (fullscreen_container_) { |
- if (rect.IsEmpty()) |
- fullscreen_container_->Invalidate(); |
- else |
- fullscreen_container_->InvalidateRect(rect); |
- } else { |
- if (!container_ || position_.IsEmpty()) |
- return; // Nothing to do. |
- if (rect.IsEmpty()) |
- container_->invalidate(); |
- else |
- container_->invalidateRect(rect); |
- } |
-} |
- |
-void PluginInstance::ScrollRect(int dx, int dy, const gfx::Rect& rect) { |
- if (fullscreen_container_) { |
- fullscreen_container_->ScrollRect(dx, dy, rect); |
- } else { |
- if (full_frame_) { |
- container_->scrollRect(dx, dy, rect); |
- } else { |
- // Can't do optimized scrolling since there could be other elements on top |
- // of us. |
- InvalidateRect(rect); |
- } |
- } |
-} |
- |
-unsigned PluginInstance::GetBackingTextureId() { |
- if (!bound_graphics_3d()) |
- return 0; |
- |
- return bound_graphics_3d()->GetBackingTextureId(); |
-} |
- |
-void PluginInstance::CommitBackingTexture() { |
- container_->commitBackingTexture(); |
-} |
- |
-PP_Var PluginInstance::GetWindowObject() { |
- if (!container_) |
- return PP_MakeUndefined(); |
- |
- WebFrame* frame = container_->element().document().frame(); |
- if (!frame) |
- return PP_MakeUndefined(); |
- |
- return ObjectVar::NPObjectToPPVar(module(), frame->windowObject()); |
-} |
- |
-PP_Var PluginInstance::GetOwnerElementObject() { |
- if (!container_) |
- return PP_MakeUndefined(); |
- return ObjectVar::NPObjectToPPVar(module(), |
- container_->scriptableObjectForElement()); |
-} |
- |
-bool PluginInstance::BindGraphics(PP_Resource graphics_id) { |
- if (!graphics_id) { |
- // Special-case clearing the current device. |
- if (bound_graphics_.get()) { |
- if (bound_graphics_2d()) { |
- bound_graphics_2d()->BindToInstance(NULL); |
- } else if (bound_graphics_.get()) { |
- bound_graphics_3d()->SetSwapBuffersCallback(NULL); |
- bound_graphics_3d()->BindToInstance(NULL); |
- } |
- InvalidateRect(gfx::Rect()); |
- } |
- bound_graphics_ = NULL; |
- return true; |
- } |
- |
- scoped_refptr<Graphics2D> graphics_2d = |
- Resource::GetAs<Graphics2D>(graphics_id); |
- scoped_refptr<Graphics3D> graphics_3d = |
- Resource::GetAs<Graphics3D>(graphics_id); |
- |
- if (graphics_2d) { |
- if (!graphics_2d->BindToInstance(this)) |
- return false; // Can't bind to more than one instance. |
- |
- // See http://crbug.com/49403: this can be further optimized by keeping the |
- // old device around and painting from it. |
- if (bound_graphics_2d()) { |
- // Start the new image with the content of the old image until the plugin |
- // repaints. |
- const SkBitmap* old_backing_bitmap = |
- bound_graphics_2d()->image_data()->GetMappedBitmap(); |
- SkRect old_size = SkRect::MakeWH( |
- SkScalar(static_cast<float>(old_backing_bitmap->width())), |
- SkScalar(static_cast<float>(old_backing_bitmap->height()))); |
- |
- SkCanvas canvas(*graphics_2d->image_data()->GetMappedBitmap()); |
- canvas.drawBitmap(*old_backing_bitmap, 0, 0); |
- |
- // Fill in any extra space with white. |
- canvas.clipRect(old_size, SkRegion::kDifference_Op); |
- canvas.drawARGB(255, 255, 255, 255); |
- } |
- |
- bound_graphics_ = graphics_2d; |
- // BindToInstance will have invalidated the plugin if necessary. |
- } else if (graphics_3d) { |
- if (!graphics_3d->BindToInstance(this)) |
- return false; |
- |
- bound_graphics_ = graphics_3d; |
- bound_graphics_3d()->SetSwapBuffersCallback( |
- NewCallback(this, &PluginInstance::CommitBackingTexture)); |
- } |
- |
- return true; |
-} |
- |
-bool PluginInstance::SetCursor(PP_CursorType_Dev type) { |
- cursor_.reset(new WebCursorInfo(static_cast<WebCursorInfo::Type>(type))); |
- return true; |
-} |
- |
-PP_Var PluginInstance::ExecuteScript(PP_Var script, PP_Var* exception) { |
- TryCatch try_catch(module(), exception); |
- if (try_catch.has_exception()) |
- return PP_MakeUndefined(); |
- |
- // Convert the script into an inconvenient NPString object. |
- scoped_refptr<StringVar> script_string(StringVar::FromPPVar(script)); |
- if (!script_string) { |
- try_catch.SetException("Script param to ExecuteScript must be a string."); |
- return PP_MakeUndefined(); |
- } |
- NPString np_script; |
- np_script.UTF8Characters = script_string->value().c_str(); |
- np_script.UTF8Length = script_string->value().length(); |
- |
- // Get the current frame to pass to the evaluate function. |
- WebFrame* frame = container_->element().document().frame(); |
- if (!frame) { |
- try_catch.SetException("No frame to execute script in."); |
- return PP_MakeUndefined(); |
- } |
- |
- NPVariant result; |
- bool ok = WebBindings::evaluate(NULL, frame->windowObject(), &np_script, |
- &result); |
- if (!ok) { |
- // TODO(brettw) bug 54011: The TryCatch isn't working properly and |
- // doesn't actually catch this exception. |
- try_catch.SetException("Exception caught"); |
- WebBindings::releaseVariantValue(&result); |
- return PP_MakeUndefined(); |
- } |
- |
- PP_Var ret = Var::NPVariantToPPVar(module_, &result); |
- WebBindings::releaseVariantValue(&result); |
- return ret; |
-} |
- |
-void PluginInstance::Delete() { |
- instance_interface_->DidDestroy(pp_instance()); |
- |
- if (fullscreen_container_) { |
- fullscreen_container_->Destroy(); |
- fullscreen_container_ = NULL; |
- } |
- container_ = NULL; |
-} |
- |
-bool PluginInstance::Initialize(WebPluginContainer* container, |
- const std::vector<std::string>& arg_names, |
- const std::vector<std::string>& arg_values, |
- bool full_frame) { |
- container_ = container; |
- full_frame_ = full_frame; |
- |
- size_t argc = 0; |
- scoped_array<const char*> argn(new const char*[arg_names.size()]); |
- scoped_array<const char*> argv(new const char*[arg_names.size()]); |
- for (size_t i = 0; i < arg_names.size(); ++i) { |
- argn[argc] = arg_names[i].c_str(); |
- argv[argc] = arg_values[i].c_str(); |
- argc++; |
- } |
- |
- return PPBoolToBool(instance_interface_->DidCreate(pp_instance(), |
- argc, |
- argn.get(), |
- argv.get())); |
-} |
- |
-bool PluginInstance::HandleDocumentLoad(URLLoader* loader) { |
- Resource::ScopedResourceId resource(loader); |
- return PPBoolToBool(instance_interface_->HandleDocumentLoad(pp_instance(), |
- resource.id)); |
-} |
- |
-bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event, |
- WebCursorInfo* cursor_info) { |
- std::vector<PP_InputEvent> pp_events; |
- CreatePPEvent(event, &pp_events); |
- |
- // Each input event may generate more than one PP_InputEvent. |
- bool rv = false; |
- for (size_t i = 0; i < pp_events.size(); i++) { |
- rv |= PPBoolToBool(instance_interface_->HandleInputEvent(pp_instance(), |
- &pp_events[i])); |
- } |
- |
- if (cursor_.get()) |
- *cursor_info = *cursor_; |
- return rv; |
-} |
- |
-PP_Var PluginInstance::GetInstanceObject() { |
- return instance_interface_->GetInstanceObject(pp_instance()); |
-} |
- |
-void PluginInstance::ViewChanged(const gfx::Rect& position, |
- const gfx::Rect& clip) { |
- if (position.size() != position_.size() && bound_graphics_3d()) { |
- // TODO(apatrick): This is a hack to force the back buffer to resize. |
- // It is obviously wrong to call SwapBuffers when a partial frame has |
- // potentially been rendered. Plan is to embed resize commands in the |
- // command buffer just before ViewChanged is called. |
- bound_graphics_3d()->ResizeBackingTexture(position.size()); |
- bound_graphics_3d()->SwapBuffers(); |
- } |
- |
- position_ = position; |
- |
- if (clip.IsEmpty()) { |
- // WebKit can give weird (x,y) positions for empty clip rects (since the |
- // position technically doesn't matter). But we want to make these |
- // consistent since this is given to the plugin, so force everything to 0 |
- // in the "everything is clipped" case. |
- clip_ = gfx::Rect(); |
- } else { |
- clip_ = clip; |
- } |
- |
- PP_Rect pp_position, pp_clip; |
- RectToPPRect(position_, &pp_position); |
- RectToPPRect(clip_, &pp_clip); |
- instance_interface_->DidChangeView(pp_instance(), &pp_position, &pp_clip); |
-} |
- |
-void PluginInstance::SetWebKitFocus(bool has_focus) { |
- if (has_webkit_focus_ == has_focus) |
- return; |
- |
- bool old_plugin_focus = PluginHasFocus(); |
- has_webkit_focus_ = has_focus; |
- if (PluginHasFocus() != old_plugin_focus) { |
- instance_interface_->DidChangeFocus(pp_instance(), |
- BoolToPPBool(PluginHasFocus())); |
- } |
-} |
- |
-void PluginInstance::SetContentAreaFocus(bool has_focus) { |
- if (has_content_area_focus_ == has_focus) |
- return; |
- |
- bool old_plugin_focus = PluginHasFocus(); |
- has_content_area_focus_ = has_focus; |
- if (PluginHasFocus() != old_plugin_focus) { |
- instance_interface_->DidChangeFocus(pp_instance(), |
- BoolToPPBool(PluginHasFocus())); |
- } |
-} |
- |
-void PluginInstance::ViewInitiatedPaint() { |
- if (bound_graphics_2d()) |
- bound_graphics_2d()->ViewInitiatedPaint(); |
-} |
- |
-void PluginInstance::ViewFlushedPaint() { |
- if (bound_graphics_2d()) |
- bound_graphics_2d()->ViewFlushedPaint(); |
-} |
- |
-bool PluginInstance::GetBitmapForOptimizedPluginPaint( |
- const gfx::Rect& paint_bounds, |
- TransportDIB** dib, |
- gfx::Rect* location, |
- gfx::Rect* clip) { |
- if (!always_on_top_) |
- return false; |
- if (!bound_graphics_2d() || !bound_graphics_2d()->is_always_opaque()) |
- return false; |
- |
- // We specifically want to compare against the area covered by the backing |
- // store when seeing if we cover the given paint bounds, since the backing |
- // store could be smaller than the declared plugin area. |
- ImageData* image_data = bound_graphics_2d()->image_data(); |
- gfx::Rect plugin_backing_store_rect(position_.origin(), |
- gfx::Size(image_data->width(), |
- image_data->height())); |
- gfx::Rect clip_page(clip_); |
- clip_page.Offset(position_.origin()); |
- gfx::Rect plugin_paint_rect = plugin_backing_store_rect.Intersect(clip_page); |
- if (!plugin_paint_rect.Contains(paint_bounds)) |
- return false; |
- |
- *dib = image_data->platform_image()->GetTransportDIB(); |
- *location = plugin_backing_store_rect; |
- *clip = clip_page; |
- return true; |
-} |
- |
-string16 PluginInstance::GetSelectedText(bool html) { |
- if (!LoadSelectionInterface()) |
- return string16(); |
- |
- PP_Var rv = plugin_selection_interface_->GetSelectedText(pp_instance(), |
- BoolToPPBool(html)); |
- scoped_refptr<StringVar> string(StringVar::FromPPVar(rv)); |
- Var::PluginReleasePPVar(rv); // Release the ref the plugin transfered to us. |
- if (!string) |
- return string16(); |
- return UTF8ToUTF16(string->value()); |
-} |
- |
-string16 PluginInstance::GetLinkAtPosition(const gfx::Point& point) { |
- if (!LoadPrivateInterface()) |
- return string16(); |
- |
- PP_Point p; |
- p.x = point.x(); |
- p.y = point.y(); |
- PP_Var rv = plugin_private_interface_->GetLinkAtPosition(pp_instance(), p); |
- scoped_refptr<StringVar> string(StringVar::FromPPVar(rv)); |
- Var::PluginReleasePPVar(rv); // Release the ref the plugin transfered to us. |
- if (!string) |
- return string16(); |
- return UTF8ToUTF16(string->value()); |
-} |
- |
-void PluginInstance::Zoom(double factor, bool text_only) { |
- if (!LoadZoomInterface()) |
- return; |
- plugin_zoom_interface_->Zoom(pp_instance(), factor, BoolToPPBool(text_only)); |
-} |
- |
-bool PluginInstance::StartFind(const string16& search_text, |
- bool case_sensitive, |
- int identifier) { |
- if (!LoadFindInterface()) |
- return false; |
- find_identifier_ = identifier; |
- return PPBoolToBool( |
- plugin_find_interface_->StartFind( |
- pp_instance(), |
- UTF16ToUTF8(search_text.c_str()).c_str(), |
- BoolToPPBool(case_sensitive))); |
-} |
- |
-void PluginInstance::SelectFindResult(bool forward) { |
- if (LoadFindInterface()) |
- plugin_find_interface_->SelectFindResult(pp_instance(), |
- BoolToPPBool(forward)); |
-} |
- |
-void PluginInstance::StopFind() { |
- if (!LoadFindInterface()) |
- return; |
- find_identifier_ = -1; |
- plugin_find_interface_->StopFind(pp_instance()); |
-} |
- |
-bool PluginInstance::LoadFindInterface() { |
- if (!plugin_find_interface_) { |
- plugin_find_interface_ = |
- reinterpret_cast<const PPP_Find_Dev*>(module_->GetPluginInterface( |
- PPP_FIND_DEV_INTERFACE)); |
- } |
- |
- return !!plugin_find_interface_; |
-} |
- |
-bool PluginInstance::LoadPrivateInterface() { |
- if (!plugin_private_interface_) { |
- plugin_private_interface_ = |
- reinterpret_cast<const PPP_Private*>(module_->GetPluginInterface( |
- PPP_PRIVATE_INTERFACE)); |
- } |
- |
- return !!plugin_private_interface_; |
-} |
- |
-bool PluginInstance::LoadSelectionInterface() { |
- if (!plugin_selection_interface_) { |
- plugin_selection_interface_ = |
- reinterpret_cast<const PPP_Selection_Dev*>(module_->GetPluginInterface( |
- PPP_SELECTION_DEV_INTERFACE)); |
- } |
- |
- return !!plugin_selection_interface_; |
-} |
- |
-bool PluginInstance::LoadZoomInterface() { |
- if (!plugin_zoom_interface_) { |
- plugin_zoom_interface_ = |
- reinterpret_cast<const PPP_Zoom_Dev*>(module_->GetPluginInterface( |
- PPP_ZOOM_DEV_INTERFACE)); |
- } |
- |
- return !!plugin_zoom_interface_; |
-} |
- |
-bool PluginInstance::PluginHasFocus() const { |
- return has_webkit_focus_ && has_content_area_focus_; |
-} |
- |
-bool PluginInstance::GetPreferredPrintOutputFormat( |
- PP_PrintOutputFormat_Dev* format) { |
- if (!plugin_print_interface_) { |
- plugin_print_interface_ = |
- reinterpret_cast<const PPP_Printing_Dev*>(module_->GetPluginInterface( |
- PPP_PRINTING_DEV_INTERFACE)); |
- } |
- if (!plugin_print_interface_) |
- return false; |
- uint32_t format_count = 0; |
- PP_PrintOutputFormat_Dev* supported_formats = |
- plugin_print_interface_->QuerySupportedFormats(pp_instance(), |
- &format_count); |
- if (!supported_formats) |
- return false; |
- |
- bool found_supported_format = false; |
- for (uint32_t index = 0; index < format_count; index++) { |
- if (supported_formats[index] == PP_PRINTOUTPUTFORMAT_PDF) { |
- // If we found PDF, we are done. |
- found_supported_format = true; |
- *format = PP_PRINTOUTPUTFORMAT_PDF; |
- break; |
- } else if (supported_formats[index] == PP_PRINTOUTPUTFORMAT_RASTER) { |
- // We found raster. Keep looking. |
- found_supported_format = true; |
- *format = PP_PRINTOUTPUTFORMAT_RASTER; |
- } |
- } |
- PluginModule::GetCore()->MemFree(supported_formats); |
- return found_supported_format; |
-} |
- |
-bool PluginInstance::SupportsPrintInterface() { |
- PP_PrintOutputFormat_Dev format; |
- return GetPreferredPrintOutputFormat(&format); |
-} |
- |
-int PluginInstance::PrintBegin(const gfx::Rect& printable_area, |
- int printer_dpi) { |
- PP_PrintOutputFormat_Dev format; |
- if (!GetPreferredPrintOutputFormat(&format)) { |
- // PrintBegin should not have been called since SupportsPrintInterface |
- // would have returned false; |
- NOTREACHED(); |
- return 0; |
- } |
- |
- PP_PrintSettings_Dev print_settings; |
- RectToPPRect(printable_area, &print_settings.printable_area); |
- print_settings.dpi = printer_dpi; |
- print_settings.orientation = PP_PRINTORIENTATION_NORMAL; |
- print_settings.grayscale = PP_FALSE; |
- print_settings.format = format; |
- int num_pages = plugin_print_interface_->Begin(pp_instance(), |
- &print_settings); |
- if (!num_pages) |
- return 0; |
- current_print_settings_ = print_settings; |
-#if defined (OS_LINUX) |
- num_pages_ = num_pages; |
- pdf_output_done_ = false; |
-#endif // (OS_LINUX) |
- return num_pages; |
-} |
- |
-bool PluginInstance::PrintPage(int page_number, WebKit::WebCanvas* canvas) { |
- DCHECK(plugin_print_interface_); |
- PP_PrintPageNumberRange_Dev page_range; |
-#if defined(OS_LINUX) |
- if (current_print_settings_.format == PP_PRINTOUTPUTFORMAT_PDF) { |
- // On Linux we will try and output all pages as PDF in the first call to |
- // PrintPage. This is a temporary hack. |
- // TODO(sanjeevr): Remove this hack and fix this by changing the print |
- // interfaces for WebFrame and WebPlugin. |
- if (page_number != 0) |
- return pdf_output_done_; |
- page_range.first_page_number = 0; |
- page_range.last_page_number = num_pages_ - 1; |
- } |
-#else // defined(OS_LINUX) |
- page_range.first_page_number = page_range.last_page_number = page_number; |
-#endif // defined(OS_LINUX) |
- |
- PP_Resource print_output = |
- plugin_print_interface_->PrintPages(pp_instance(), &page_range, 1); |
- |
- if (!print_output) |
- return false; |
- |
- bool ret = false; |
- |
- if (current_print_settings_.format == PP_PRINTOUTPUTFORMAT_PDF) |
- ret = PrintPDFOutput(print_output, canvas); |
- else if (current_print_settings_.format == PP_PRINTOUTPUTFORMAT_RASTER) |
- ret = PrintRasterOutput(print_output, canvas); |
- |
- // Now we need to release the print output resource. |
- PluginModule::GetCore()->ReleaseResource(print_output); |
- |
- return ret; |
-} |
- |
-void PluginInstance::PrintEnd() { |
- DCHECK(plugin_print_interface_); |
- if (plugin_print_interface_) |
- plugin_print_interface_->End(pp_instance()); |
- memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); |
-#if defined(OS_MACOSX) |
- last_printed_page_ = NULL; |
-#elif defined(OS_LINUX) |
- num_pages_ = 0; |
- pdf_output_done_ = false; |
-#endif // defined(OS_LINUX) |
-} |
- |
-bool PluginInstance::IsFullscreen() { |
- return fullscreen_container_ != NULL; |
-} |
- |
-bool PluginInstance::SetFullscreen(bool fullscreen) { |
- bool is_fullscreen = (fullscreen_container_ != NULL); |
- if (fullscreen == is_fullscreen) |
- return true; |
- VLOG(1) << "Setting fullscreen to " << (fullscreen ? "on" : "off"); |
- if (fullscreen) { |
- fullscreen_container_ = delegate_->CreateFullscreenContainer(this); |
- } else { |
- fullscreen_container_->Destroy(); |
- fullscreen_container_ = NULL; |
- // TODO(piman): currently the fullscreen container resizes the plugin to the |
- // fullscreen size so we need to reset the size here. Eventually it will |
- // transparently scale and this won't be necessary. |
- if (container_) { |
- container_->reportGeometry(); |
- container_->invalidate(); |
- } |
- } |
- return true; |
-} |
- |
-bool PluginInstance::NavigateToURL(const char* url, const char* target) { |
- if (!url || !target || !container_) |
- return false; |
- |
- WebDocument document = container_->element().document(); |
- GURL complete_url = document.completeURL(WebString::fromUTF8(url)); |
- // Don't try to deal with the security issues of javascript. |
- if (complete_url.SchemeIs("javascript")) |
- return false; |
- |
- WebURLRequest request(complete_url); |
- document.frame()->setReferrerForRequest(request, GURL()); |
- request.setHTTPMethod(WebString::fromUTF8("GET")); |
- request.setFirstPartyForCookies(document.firstPartyForCookies()); |
- |
- WebString target_str = WebString::fromUTF8(target); |
- container_->loadFrameRequest(request, target_str, false, NULL); |
- return true; |
-} |
- |
-bool PluginInstance::PrintPDFOutput(PP_Resource print_output, |
- WebKit::WebCanvas* canvas) { |
- scoped_refptr<Buffer> buffer(Resource::GetAs<Buffer>(print_output)); |
- if (!buffer.get() || !buffer->is_mapped() || !buffer->size()) { |
- NOTREACHED(); |
- return false; |
- } |
-#if defined(OS_WIN) |
- // For Windows, we need the PDF DLL to render the output PDF to a DC. |
- HMODULE pdf_module = GetModuleHandle(L"pdf.dll"); |
- if (!pdf_module) |
- return false; |
- RenderPDFPageToDCProc render_proc = |
- reinterpret_cast<RenderPDFPageToDCProc>( |
- GetProcAddress(pdf_module, "RenderPDFPageToDC")); |
- if (!render_proc) |
- return false; |
-#endif // defined(OS_WIN) |
- |
- bool ret = false; |
-#if defined(OS_LINUX) |
- // On Linux we need to get the backing PdfPsMetafile and write the bits |
- // directly. |
- cairo_t* context = canvas->beginPlatformPaint(); |
- printing::NativeMetafile* metafile = |
- printing::NativeMetafile::FromCairoContext(context); |
- DCHECK(metafile); |
- if (metafile) { |
- ret = metafile->SetRawData(buffer->mapped_buffer(), buffer->size()); |
- if (ret) |
- pdf_output_done_ = true; |
- } |
- canvas->endPlatformPaint(); |
-#elif defined(OS_MACOSX) |
- printing::NativeMetafile metafile; |
- // Create a PDF metafile and render from there into the passed in context. |
- if (metafile.Init(buffer->mapped_buffer(), buffer->size())) { |
- // Flip the transform. |
- CGContextSaveGState(canvas); |
- CGContextTranslateCTM(canvas, 0, |
- current_print_settings_.printable_area.size.height); |
- CGContextScaleCTM(canvas, 1.0, -1.0); |
- CGRect page_rect; |
- page_rect.origin.x = current_print_settings_.printable_area.point.x; |
- page_rect.origin.y = current_print_settings_.printable_area.point.y; |
- page_rect.size.width = current_print_settings_.printable_area.size.width; |
- page_rect.size.height = current_print_settings_.printable_area.size.height; |
- |
- ret = metafile.RenderPage(1, canvas, page_rect, true, false, true, true); |
- CGContextRestoreGState(canvas); |
- } |
-#elif defined(OS_WIN) |
- // On Windows, we now need to render the PDF to the DC that backs the |
- // supplied canvas. |
- skia::VectorPlatformDevice& device = |
- static_cast<skia::VectorPlatformDevice&>( |
- canvas->getTopPlatformDevice()); |
- HDC dc = device.getBitmapDC(); |
- gfx::Size size_in_pixels; |
- size_in_pixels.set_width( |
- printing::ConvertUnit(current_print_settings_.printable_area.size.width, |
- static_cast<int>(printing::kPointsPerInch), |
- current_print_settings_.dpi)); |
- size_in_pixels.set_height( |
- printing::ConvertUnit(current_print_settings_.printable_area.size.height, |
- static_cast<int>(printing::kPointsPerInch), |
- current_print_settings_.dpi)); |
- // We need to render using the actual printer DPI (rendering to a smaller |
- // set of pixels leads to a blurry output). However, we need to counter the |
- // scaling up that will happen in the browser. |
- XFORM xform = {0}; |
- xform.eM11 = xform.eM22 = static_cast<float>(printing::kPointsPerInch) / |
- static_cast<float>(current_print_settings_.dpi); |
- ModifyWorldTransform(dc, &xform, MWT_LEFTMULTIPLY); |
- |
- ret = render_proc(buffer->mapped_buffer(), buffer->size(), 0, dc, |
- current_print_settings_.dpi, current_print_settings_.dpi, |
- 0, 0, size_in_pixels.width(), |
- size_in_pixels.height(), true, false, true, true); |
-#endif // defined(OS_WIN) |
- |
- return ret; |
-} |
- |
-bool PluginInstance::PrintRasterOutput(PP_Resource print_output, |
- WebKit::WebCanvas* canvas) { |
- scoped_refptr<ImageData> image(Resource::GetAs<ImageData>(print_output)); |
- if (!image.get() || !image->is_mapped()) |
- return false; |
- |
- const SkBitmap* bitmap = image->GetMappedBitmap(); |
- if (!bitmap) |
- return false; |
- |
- // Draw the printed image into the supplied canvas. |
- SkIRect src_rect; |
- src_rect.set(0, 0, bitmap->width(), bitmap->height()); |
- SkRect dest_rect; |
- dest_rect.set( |
- SkIntToScalar(current_print_settings_.printable_area.point.x), |
- SkIntToScalar(current_print_settings_.printable_area.point.y), |
- SkIntToScalar(current_print_settings_.printable_area.point.x + |
- current_print_settings_.printable_area.size.width), |
- SkIntToScalar(current_print_settings_.printable_area.point.y + |
- current_print_settings_.printable_area.size.height)); |
- bool draw_to_canvas = true; |
- gfx::Rect dest_rect_gfx; |
- dest_rect_gfx.set_x(current_print_settings_.printable_area.point.x); |
- dest_rect_gfx.set_y(current_print_settings_.printable_area.point.y); |
- dest_rect_gfx.set_width(current_print_settings_.printable_area.size.width); |
- dest_rect_gfx.set_height(current_print_settings_.printable_area.size.height); |
- |
-#if defined(OS_WIN) |
- // Since this is a raster output, the size of the bitmap can be |
- // huge (especially at high printer DPIs). On Windows, this can |
- // result in a HUGE EMF (on Mac and Linux the output goes to PDF |
- // which appears to Flate compress the bitmap). So, if this bitmap |
- // is larger than 20 MB, we save the bitmap as a JPEG into the EMF |
- // DC. Note: We chose JPEG over PNG because JPEG compression seems |
- // way faster (about 4 times faster). |
- static const int kCompressionThreshold = 20 * 1024 * 1024; |
- if (bitmap->getSize() > kCompressionThreshold) { |
- DrawJPEGToPlatformDC(*bitmap, dest_rect_gfx, canvas); |
- draw_to_canvas = false; |
- } |
-#endif // defined(OS_WIN) |
-#if defined(OS_MACOSX) |
- draw_to_canvas = false; |
- DrawSkBitmapToCanvas(*bitmap, canvas, dest_rect_gfx, |
- current_print_settings_.printable_area.size.height); |
- // See comments in the header file. |
- last_printed_page_ = image; |
-#else // defined(OS_MACOSX) |
- if (draw_to_canvas) |
- canvas->drawBitmapRect(*bitmap, &src_rect, dest_rect); |
-#endif // defined(OS_MACOSX) |
- return true; |
-} |
- |
-#if defined(OS_WIN) |
-bool PluginInstance::DrawJPEGToPlatformDC( |
- const SkBitmap& bitmap, |
- const gfx::Rect& printable_area, |
- WebKit::WebCanvas* canvas) { |
- skia::VectorPlatformDevice& device = |
- static_cast<skia::VectorPlatformDevice&>( |
- canvas->getTopPlatformDevice()); |
- HDC dc = device.getBitmapDC(); |
- // TODO(sanjeevr): This is a temporary hack. If we output a JPEG |
- // to the EMF, the EnumEnhMetaFile call fails in the browser |
- // process. The failure also happens if we output nothing here. |
- // We need to investigate the reason for this failure and fix it. |
- // In the meantime this temporary hack of drawing an empty |
- // rectangle in the DC gets us by. |
- Rectangle(dc, 0, 0, 0, 0); |
- |
- // Ideally we should add JPEG compression to the VectorPlatformDevice class |
- // However, Skia currently has no JPEG compression code and we cannot |
- // depend on gfx/jpeg_codec.h in Skia. So we do the compression here. |
- SkAutoLockPixels lock(bitmap); |
- DCHECK(bitmap.getConfig() == SkBitmap::kARGB_8888_Config); |
- const uint32_t* pixels = |
- static_cast<const uint32_t*>(bitmap.getPixels()); |
- std::vector<unsigned char> compressed_image; |
- base::TimeTicks start_time = base::TimeTicks::Now(); |
- bool encoded = gfx::JPEGCodec::Encode( |
- reinterpret_cast<const unsigned char*>(pixels), |
- gfx::JPEGCodec::FORMAT_BGRA, bitmap.width(), bitmap.height(), |
- static_cast<int>(bitmap.rowBytes()), 100, &compressed_image); |
- UMA_HISTOGRAM_TIMES("PepperPluginPrint.RasterBitmapCompressTime", |
- base::TimeTicks::Now() - start_time); |
- if (!encoded) { |
- NOTREACHED(); |
- return false; |
- } |
- BITMAPINFOHEADER bmi = {0}; |
- gfx::CreateBitmapHeader(bitmap.width(), bitmap.height(), &bmi); |
- bmi.biCompression = BI_JPEG; |
- bmi.biSizeImage = compressed_image.size(); |
- bmi.biHeight = -bmi.biHeight; |
- StretchDIBits(dc, printable_area.x(), printable_area.y(), |
- printable_area.width(), printable_area.height(), |
- 0, 0, bitmap.width(), bitmap.height(), |
- &compressed_image.front(), |
- reinterpret_cast<const BITMAPINFO*>(&bmi), |
- DIB_RGB_COLORS, SRCCOPY); |
- return true; |
-} |
-#endif // OS_WIN |
- |
-#if defined(OS_MACOSX) |
-void PluginInstance::DrawSkBitmapToCanvas( |
- const SkBitmap& bitmap, WebKit::WebCanvas* canvas, |
- const gfx::Rect& dest_rect, |
- int canvas_height) { |
- SkAutoLockPixels lock(bitmap); |
- DCHECK(bitmap.getConfig() == SkBitmap::kARGB_8888_Config); |
- base::mac::ScopedCFTypeRef<CGDataProviderRef> data_provider( |
- CGDataProviderCreateWithData( |
- NULL, bitmap.getAddr32(0, 0), |
- bitmap.rowBytes() * bitmap.height(), NULL)); |
- base::mac::ScopedCFTypeRef<CGImageRef> image( |
- CGImageCreate( |
- bitmap.width(), bitmap.height(), |
- 8, 32, bitmap.rowBytes(), |
- mac_util::GetSystemColorSpace(), |
- kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, |
- data_provider, NULL, false, kCGRenderingIntentDefault)); |
- |
- // Flip the transform |
- CGContextSaveGState(canvas); |
- CGContextTranslateCTM(canvas, 0, canvas_height); |
- CGContextScaleCTM(canvas, 1.0, -1.0); |
- |
- CGRect bounds; |
- bounds.origin.x = dest_rect.x(); |
- bounds.origin.y = canvas_height - dest_rect.y() - dest_rect.height(); |
- bounds.size.width = dest_rect.width(); |
- bounds.size.height = dest_rect.height(); |
- |
- CGContextDrawImage(canvas, bounds, image); |
- CGContextRestoreGState(canvas); |
-} |
-#endif // defined(OS_MACOSX) |
- |
-Graphics2D* PluginInstance::bound_graphics_2d() const { |
- if (bound_graphics_.get() == NULL) |
- return NULL; |
- |
- return bound_graphics_->Cast<Graphics2D>(); |
-} |
- |
-Graphics3D* PluginInstance::bound_graphics_3d() const { |
- if (bound_graphics_.get() == NULL) |
- return NULL; |
- |
- return bound_graphics_->Cast<Graphics3D>(); |
-} |
- |
-} // namespace pepper |