diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-10 21:17:48 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-10 21:17:48 +0000 |
commit | 7a1f7c6f6c982287b3f6bb2acded619f3824416c (patch) | |
tree | 82ff404c4bcf84520c21ea7f0526ad5a40661641 /ppapi | |
parent | bafaee12825a06890f114a282880e135a8b0b1ae (diff) | |
download | chromium_src-7a1f7c6f6c982287b3f6bb2acded619f3824416c.zip chromium_src-7a1f7c6f6c982287b3f6bb2acded619f3824416c.tar.gz chromium_src-7a1f7c6f6c982287b3f6bb2acded619f3824416c.tar.bz2 |
Make the Pepper proxy support in-process font rendering.
This implements a WebKit thread in the PPAPI plugin process so we can do the
font calls without IPC. The existing font support was refactored into
a virtual class (to prevent PPAPI from depending on WebKit and creating a
circular GYP dependency).
This moves the renderer sandbox support into content/common so that it can
be used by the PPAPI process.
Review URL: http://codereview.chromium.org/6981001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84856 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
34 files changed, 705 insertions, 494 deletions
diff --git a/ppapi/ppapi.gyp b/ppapi/ppapi.gyp index 898476a..8d1d6c0 100644 --- a/ppapi/ppapi.gyp +++ b/ppapi/ppapi.gyp @@ -2,6 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +# This is the "public" ppapi.gyp file, which must have dependencies on the +# redistributable portions of PPAPI only. This prevents circular dependencies +# in the .gyp files (since ppapi_internal depends on parts of Chrome). + { 'variables': { 'chromium_code': 1, # Use higher warning level. @@ -26,7 +30,5 @@ 'includes': [ 'ppapi_cpp.gypi', 'ppapi_gl.gypi', - 'ppapi_shared_proxy.gypi', - 'ppapi_tests.gypi', ], } diff --git a/ppapi/ppapi_internal.gyp b/ppapi/ppapi_internal.gyp new file mode 100644 index 0000000..520c3cc --- /dev/null +++ b/ppapi/ppapi_internal.gyp @@ -0,0 +1,30 @@ +# 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. + +{ + 'variables': { + 'chromium_code': 1, # Use higher warning level. + }, + 'target_defaults': { + 'conditions': [ + # Linux shared libraries should always be built -fPIC. + # + # TODO(ajwong): For internal pepper plugins, which are statically linked + # into chrome, do we want to build w/o -fPIC? If so, how can we express + # that in the build system? + ['OS=="linux" or OS=="openbsd" or OS=="freebsd" or OS=="solaris"', { + 'cflags': ['-fPIC', '-fvisibility=hidden'], + + # This is needed to make the Linux shlib build happy. Without this, + # -fvisibility=hidden gets stripped by the exclusion in common.gypi + # that is triggered when a shared library build is specified. + 'cflags/': [['include', '^-fvisibility=hidden$']], + }], + ], + }, + 'includes': [ + 'ppapi_shared_proxy.gypi', + 'ppapi_tests.gypi', + ], +} diff --git a/ppapi/ppapi_shared_proxy.gypi b/ppapi/ppapi_shared_proxy.gypi index 5cfcdc5..5656970 100644 --- a/ppapi/ppapi_shared_proxy.gypi +++ b/ppapi/ppapi_shared_proxy.gypi @@ -8,12 +8,13 @@ 'target_name': 'ppapi_shared_impl', 'type': 'static_library', 'dependencies': [ - 'ppapi_c', + 'ppapi.gyp:ppapi_c', '../base/base.gyp:base', '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', '../build/temp_gyp/googleurl.gyp:googleurl', '../skia/skia.gyp:skia', '../third_party/icu/icu.gyp:icuuc', + '../ui/gfx/surface/surface.gyp:surface', ], 'include_dirs': [ '..', @@ -28,14 +29,20 @@ 'shared_impl/char_set_impl.h', 'shared_impl/crypto_impl.cc', 'shared_impl/crypto_impl.h', + 'shared_impl/font_impl.cc', + 'shared_impl/font_impl.h', 'shared_impl/image_data_impl.cc', 'shared_impl/image_data_impl.h', 'shared_impl/tracker_base.cc', 'shared_impl/tracker_base.h', 'shared_impl/url_util_impl.cc', 'shared_impl/url_util_impl.h', + 'shared_impl/webkit_forwarding.cc', + 'shared_impl/webkit_forwarding.h', 'thunk/enter.h', + 'thunk/ppb_font_api.h', + 'thunk/ppb_font_thunk.cc', 'thunk/ppb_graphics_2d_api.h', 'thunk/ppb_graphics_2d_thunk.cc', 'thunk/ppb_image_data_api.h', @@ -54,7 +61,9 @@ 'dependencies': [ '../ipc/ipc.gyp:ipc', '../gpu/gpu.gyp:gpu_ipc', - 'ppapi_c', + '../skia/skia.gyp:skia', + '../ui/gfx/surface/surface.gyp:surface', + 'ppapi.gyp:ppapi_c', 'ppapi_shared_impl', ], 'all_dependent_settings': { diff --git a/ppapi/ppapi_tests.gypi b/ppapi/ppapi_tests.gypi index 6d81e19..dc1d767 100644 --- a/ppapi/ppapi_tests.gypi +++ b/ppapi/ppapi_tests.gypi @@ -7,7 +7,7 @@ { 'target_name': 'ppapi_example', 'dependencies': [ - 'ppapi_cpp' + 'ppapi.gyp:ppapi_cpp' ], 'xcode_settings': { 'INFOPLIST_FILE': 'example/Info.plist', @@ -64,7 +64,7 @@ # 'target_name': 'ppapi_example_skeleton', # 'type': 'none', # 'dependencies': [ -# 'ppapi_cpp', +# 'ppapi.gyp:ppapi_cpp', # ], # 'export_dependent_setting': ['ppapi_cpp'], # 'direct_dependent_settings': { @@ -242,7 +242,7 @@ 'tests/test_var_deprecated.h', ], 'dependencies': [ - 'ppapi_cpp' + 'ppapi.gyp:ppapi_cpp' ], 'conditions': [ ['OS=="win"', { @@ -294,6 +294,7 @@ '../ipc/ipc.gyp:test_support_ipc', '../testing/gmock.gyp:gmock', '../testing/gtest.gyp:gtest', + '../ui/gfx/surface/surface.gyp:surface', ], 'sources': [ 'proxy/run_all_unittests.cc', diff --git a/ppapi/proxy/DEPS b/ppapi/proxy/DEPS index 5c5b2d4..a159be3 100644 --- a/ppapi/proxy/DEPS +++ b/ppapi/proxy/DEPS @@ -2,6 +2,8 @@ include_rules = [ "+base", "+ipc", "+gpu", + "+skia", + "+ui/gfx/surface", # We don't want the proxy to depend on the C++ layer, which is appropriate # for plugins only. However, the completion callback factory is a very useful @@ -10,3 +12,4 @@ include_rules = [ "-ppapi/cpp", "+ppapi/cpp/completion_callback.h" ] + diff --git a/ppapi/proxy/dispatcher.cc b/ppapi/proxy/dispatcher.cc index b34ce48..ef14d08 100644 --- a/ppapi/proxy/dispatcher.cc +++ b/ppapi/proxy/dispatcher.cc @@ -181,6 +181,7 @@ InterfaceList* InterfaceList::GetInstance() { Dispatcher::Dispatcher(base::ProcessHandle remote_process_handle, GetInterfaceFunc local_get_interface) : ProxyChannel(remote_process_handle), + dispatcher_delegate_(NULL), disallow_trusted_interfaces_(false), // TODO(brettw) make this settable. local_get_interface_(local_get_interface), callback_tracker_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { @@ -241,6 +242,11 @@ const InterfaceProxy::Info* Dispatcher::GetPPPInterfaceInfo(InterfaceID id) { return list->id_to_plugin_info_[id]; } +void Dispatcher::SetDelegate(Delegate* delegate) { + DCHECK(!dispatcher_delegate_); + dispatcher_delegate_ = delegate; +} + void Dispatcher::SetSerializationRules( VarSerializationRules* var_serialization_rules) { serialization_rules_.reset(var_serialization_rules); diff --git a/ppapi/proxy/dispatcher.h b/ppapi/proxy/dispatcher.h index 05f61d3..2dd8052 100644 --- a/ppapi/proxy/dispatcher.h +++ b/ppapi/proxy/dispatcher.h @@ -9,6 +9,8 @@ #include <string> #include <vector> +#include "base/callback.h" +#include "base/tracked_objects.h" #include "ipc/ipc_channel_proxy.h" #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_module.h" @@ -19,6 +21,11 @@ #include "ppapi/proxy/plugin_var_tracker.h" namespace pp { + +namespace shared_impl { +class WebKitForwarding; +} + namespace proxy { class VarSerializationRules; @@ -50,6 +57,17 @@ class Dispatcher : public ProxyChannel { // // DEREFERENCE ONLY ON THE I/O THREAD. virtual std::set<PP_Instance>* GetGloballySeenInstanceIDSet() = 0; + + // Returns the WebKit forwarding object used to make calls into WebKit. + // Necessary only on the plugin side. The host side can return NULL. + virtual pp::shared_impl::WebKitForwarding* GetWebKitForwarding() = 0; + + // Posts the given task to the WebKit thread associated with this plugin + // process. For host processes, this will not be called and can do + // nothing. The WebKit thread should be lazily created if it does not + // exist yet. + virtual void PostToWebKitThread(const tracked_objects::Location& from_here, + const base::Closure& task) = 0; }; virtual ~Dispatcher(); @@ -104,6 +122,8 @@ class Dispatcher : public ProxyChannel { Dispatcher(base::ProcessHandle remote_process_handle, GetInterfaceFunc local_get_interface); + void SetDelegate(Delegate* delegate); + // Setter for the derived classes to set the appropriate var serialization. // Takes ownership of the given pointer, which must be on the heap. void SetSerializationRules(VarSerializationRules* var_serialization_rules); @@ -112,6 +132,8 @@ class Dispatcher : public ProxyChannel { return disallow_trusted_interfaces_; } + Delegate* dispatcher_delegate_; + private: bool disallow_trusted_interfaces_; diff --git a/ppapi/proxy/host_dispatcher.cc b/ppapi/proxy/host_dispatcher.cc index d9fcc36..2dce10a 100644 --- a/ppapi/proxy/host_dispatcher.cc +++ b/ppapi/proxy/host_dispatcher.cc @@ -90,10 +90,13 @@ HostDispatcher::~HostDispatcher() { } bool HostDispatcher::InitHostWithChannel( - ProxyChannel::Delegate* delegate, + Delegate* delegate, const IPC::ChannelHandle& channel_handle, bool is_client) { - return Dispatcher::InitWithChannel(delegate, channel_handle, is_client); + if (!Dispatcher::InitWithChannel(delegate, channel_handle, is_client)) + return false; + SetDelegate(delegate); + return true; } // static diff --git a/ppapi/proxy/host_dispatcher.h b/ppapi/proxy/host_dispatcher.h index 9547c46..29d3c25 100644 --- a/ppapi/proxy/host_dispatcher.h +++ b/ppapi/proxy/host_dispatcher.h @@ -46,9 +46,9 @@ class HostDispatcher : public Dispatcher { // You must call this function before anything else. Returns true on success. // The delegate pointer must outlive this class, ownership is not // transferred. - virtual bool InitHostWithChannel(ProxyChannel::Delegate* delegate, - const IPC::ChannelHandle& channel_handle, - bool is_client); + virtual bool InitHostWithChannel(Delegate* delegate, + const IPC::ChannelHandle& channel_handle, + bool is_client); // The host side maintains a mapping from PP_Instance to Dispatcher so // that we can send the messages to the right channel. diff --git a/ppapi/proxy/plugin_dispatcher.cc b/ppapi/proxy/plugin_dispatcher.cc index e9a189a..2a79e91 100644 --- a/ppapi/proxy/plugin_dispatcher.cc +++ b/ppapi/proxy/plugin_dispatcher.cc @@ -79,6 +79,7 @@ bool PluginDispatcher::InitPluginWithChannel( bool is_client) { if (!Dispatcher::InitWithChannel(delegate, channel_handle, is_client)) return false; + SetDelegate(delegate); // The message filter will intercept and process certain messages directly // on the I/O thread. @@ -201,6 +202,16 @@ InstanceData* PluginDispatcher::GetInstanceData(PP_Instance instance) { return (it == instance_map_.end()) ? NULL : &it->second; } +void PluginDispatcher::PostToWebKitThread( + const tracked_objects::Location& from_here, + const base::Closure& task) { + return dispatcher_delegate_->PostToWebKitThread(from_here, task); +} + +pp::shared_impl::WebKitForwarding* PluginDispatcher::GetWebKitForwarding() { + return dispatcher_delegate_->GetWebKitForwarding(); +} + ::ppapi::shared_impl::FunctionGroupBase* PluginDispatcher::GetFunctionAPI( pp::proxy::InterfaceID id) { if (function_proxies_[id].get()) diff --git a/ppapi/proxy/plugin_dispatcher.h b/ppapi/proxy/plugin_dispatcher.h index ca260fd..959a7ac 100644 --- a/ppapi/proxy/plugin_dispatcher.h +++ b/ppapi/proxy/plugin_dispatcher.h @@ -75,6 +75,13 @@ class PluginDispatcher : public Dispatcher { // correspond to a known instance. InstanceData* GetInstanceData(PP_Instance instance); + // Posts the given task to the WebKit thread. + void PostToWebKitThread(const tracked_objects::Location& from_here, + const base::Closure& task); + + // Returns the WebKitForwarding object used to forward events to WebKit. + pp::shared_impl::WebKitForwarding* GetWebKitForwarding(); + // Returns the "new-style" function API for the given interface ID, creating // it if necessary. // TODO(brettw) this is in progress. It should be merged with the target diff --git a/ppapi/proxy/plugin_resource_tracker.cc b/ppapi/proxy/plugin_resource_tracker.cc index e499bfa..0abae90 100644 --- a/ppapi/proxy/plugin_resource_tracker.cc +++ b/ppapi/proxy/plugin_resource_tracker.cc @@ -90,17 +90,14 @@ PluginResource* PluginResourceTracker::GetResourceObject( PP_Resource PluginResourceTracker::AddResource( linked_ptr<PluginResource> object) { - if (object->host_resource().is_null()) { - // Prevent adding null resources or GetResourceObject(0) will return a - // valid pointer! - NOTREACHED(); - return 0; - } - PP_Resource plugin_resource = ++last_resource_id_; DCHECK(resource_map_.find(plugin_resource) == resource_map_.end()); resource_map_[plugin_resource] = ResourceInfo(1, object); - host_resource_map_[object->host_resource()] = plugin_resource; + if (!object->host_resource().is_null()) { + // The host resource ID will be 0 for resources that only exist in the + // plugin process. Don't add those to the list. + host_resource_map_[object->host_resource()] = plugin_resource; + } return plugin_resource; } @@ -157,7 +154,8 @@ void PluginResourceTracker::ReleasePluginResourceRef( PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(plugin_resource->instance()); HostResource host_resource = plugin_resource->host_resource(); - host_resource_map_.erase(host_resource); + if (!host_resource.is_null()) + host_resource_map_.erase(host_resource); resource_map_.erase(found); plugin_resource.reset(); diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index f5bbe65..a5decc8 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -529,39 +529,6 @@ IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBFlashNetConnector_ConnectTcpAddress, pp::proxy::HostResource /* connector */, std::string /* net_address_as_string */) -// PPB_Font. -IPC_SYNC_MESSAGE_ROUTED2_3( - PpapiHostMsg_PPBFont_Create, - PP_Instance /* instance */, - pp::proxy::SerializedFontDescription /* in_description */, - pp::proxy::HostResource /* result */, - pp::proxy::SerializedFontDescription /* out_description */, - std::string /* out_metrics */) -IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBFont_DrawTextAt, - pp::proxy::SerializedVar /* text */, - pp::proxy::PPBFont_DrawTextAt_Params /* params */, - PP_Bool /* result */) -IPC_SYNC_MESSAGE_ROUTED4_1(PpapiHostMsg_PPBFont_MeasureText, - pp::proxy::HostResource /* font */, - pp::proxy::SerializedVar /* text */, - PP_Bool /* text_is_rtl */, - PP_Bool /* override_direction */, - int32_t /* result */) -IPC_SYNC_MESSAGE_ROUTED5_1(PpapiHostMsg_PPBFont_CharacterOffsetForPixel, - pp::proxy::HostResource /* font */, - pp::proxy::SerializedVar /* text */, - PP_Bool /* text_is_rtl */, - PP_Bool /* override_direction */, - int32_t /* pixel_pos */, - uint32_t /* result */) -IPC_SYNC_MESSAGE_ROUTED5_1(PpapiHostMsg_PPBFont_PixelOffsetForCharacter, - pp::proxy::HostResource /* font */, - pp::proxy::SerializedVar /* text */, - PP_Bool /* text_is_rtl */, - PP_Bool /* override_direction */, - uint32_t /* char_offset */, - int32_t /* result */) - // PPB_Fullscreen. IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBFullscreen_SetFullscreen, PP_Instance /* instance */, diff --git a/ppapi/proxy/ppapi_param_traits.cc b/ppapi/proxy/ppapi_param_traits.cc index 420809f..20a00c8 100644 --- a/ppapi/proxy/ppapi_param_traits.cc +++ b/ppapi/proxy/ppapi_param_traits.cc @@ -267,47 +267,6 @@ void ParamTraits<pp::proxy::PPBFileRef_CreateInfo>::Log( std::string* l) { } -// PPBFont_DrawTextAt_Params --------------------------------------------------- - -// static -void ParamTraits<pp::proxy::PPBFont_DrawTextAt_Params>::Write( - Message* m, - const param_type& p) { - ParamTraits<pp::proxy::HostResource>::Write(m, p.font); - ParamTraits<pp::proxy::HostResource>::Write(m, p.image_data); - ParamTraits<PP_Bool>::Write(m, p.text_is_rtl); - ParamTraits<PP_Bool>::Write(m, p.override_direction); - ParamTraits<PP_Point>::Write(m, p.position); - ParamTraits<uint32_t>::Write(m, p.color); - ParamTraits<PP_Rect>::Write(m, p.clip); - ParamTraits<bool>::Write(m, p.clip_is_null); - ParamTraits<PP_Bool>::Write(m, p.image_data_is_opaque); -} - -// static -bool ParamTraits<pp::proxy::PPBFont_DrawTextAt_Params>::Read( - const Message* m, - void** iter, - param_type* r) { - return - ParamTraits<pp::proxy::HostResource>::Read(m, iter, &r->font) && - ParamTraits<pp::proxy::HostResource>::Read(m, iter, - &r->image_data) && - ParamTraits<PP_Bool>::Read(m, iter, &r->text_is_rtl) && - ParamTraits<PP_Bool>::Read(m, iter, &r->override_direction) && - ParamTraits<PP_Point>::Read(m, iter, &r->position) && - ParamTraits<uint32_t>::Read(m, iter, &r->color) && - ParamTraits<PP_Rect>::Read(m, iter, &r->clip) && - ParamTraits<bool>::Read(m, iter, &r->clip_is_null) && - ParamTraits<PP_Bool>::Read(m, iter, &r->image_data_is_opaque); -} - -// static -void ParamTraits<pp::proxy::PPBFont_DrawTextAt_Params>::Log( - const param_type& p, - std::string* l) { -} - // PPBURLLoader_UpdateProgress_Params ------------------------------------------ // static diff --git a/ppapi/proxy/ppapi_param_traits.h b/ppapi/proxy/ppapi_param_traits.h index 2d07191..3d6d57f 100644 --- a/ppapi/proxy/ppapi_param_traits.h +++ b/ppapi/proxy/ppapi_param_traits.h @@ -22,7 +22,6 @@ namespace proxy { class HostResource; struct PPBFileRef_CreateInfo; struct PPBFlash_DrawGlyphs_Params; -struct PPBFont_DrawTextAt_Params; struct PPBURLLoader_UpdateProgress_Params; struct SerializedDirEntry; struct SerializedFontDescription; @@ -83,14 +82,6 @@ struct ParamTraits<pp::proxy::PPBFileRef_CreateInfo> { }; template<> -struct ParamTraits<pp::proxy::PPBFont_DrawTextAt_Params> { - typedef pp::proxy::PPBFont_DrawTextAt_Params param_type; - static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, void** iter, param_type* r); - static void Log(const param_type& p, std::string* l); -}; - -template<> struct ParamTraits<pp::proxy::PPBURLLoader_UpdateProgress_Params> { typedef pp::proxy::PPBURLLoader_UpdateProgress_Params param_type; static void Write(Message* m, const param_type& p); diff --git a/ppapi/proxy/ppb_font_proxy.cc b/ppapi/proxy/ppb_font_proxy.cc index e8d58df..9d52fcc 100644 --- a/ppapi/proxy/ppb_font_proxy.cc +++ b/ppapi/proxy/ppb_font_proxy.cc @@ -4,203 +4,36 @@ #include "ppapi/proxy/ppb_font_proxy.h" +#include "base/bind.h" #include "ppapi/c/dev/ppb_font_dev.h" #include "ppapi/proxy/plugin_dispatcher.h" -#include "ppapi/proxy/plugin_resource.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppb_image_data_proxy.h" +#include "ppapi/shared_impl/resource_object_base.h" +#include "ppapi/thunk/ppb_image_data_api.h" +#include "ppapi/thunk/thunk.h" + +using ppapi::thunk::PPB_ImageData_API; +using pp::shared_impl::WebKitForwarding; namespace pp { namespace proxy { -class Font : public PluginResource { - public: - Font(const HostResource& resource); - virtual ~Font(); - - // PluginResource overrides. - virtual Font* AsFont() { return this; } - - PP_FontDescription_Dev& desc() { return desc_; } - PP_FontDescription_Dev* desc_ptr() { return &desc_; } - PP_FontMetrics_Dev& metrics() { return metrics_; } - - private: - PP_FontDescription_Dev desc_; - PP_FontMetrics_Dev metrics_; - - DISALLOW_COPY_AND_ASSIGN(Font); -}; - -Font::Font(const HostResource& resource) : PluginResource(resource) { - memset(&desc_, 0, sizeof(PP_FontDescription_Dev)); - desc_.face.type = PP_VARTYPE_UNDEFINED; - memset(&metrics_, 0, sizeof(PP_FontMetrics_Dev)); -} - -Font::~Font() { - PluginVarTracker::GetInstance()->Release(desc_.face); -} - namespace { -PP_Resource Create(PP_Instance instance, - const PP_FontDescription_Dev* description) { - PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); - if (!dispatcher) - return 0; - - SerializedFontDescription in_description; - in_description.SetFromPPFontDescription(dispatcher, *description, true); - - HostResource result; - SerializedFontDescription out_description; - std::string out_metrics; - dispatcher->Send(new PpapiHostMsg_PPBFont_Create( - INTERFACE_ID_PPB_FONT, - instance, in_description, &result, &out_description, &out_metrics)); - - if (result.is_null()) - return 0; // Failure creating font. - - linked_ptr<Font> object(new Font(result)); - out_description.SetToPPFontDescription(dispatcher, object->desc_ptr(), true); - - // Convert the metrics, this is just serialized as a string of bytes. - if (out_metrics.size() != sizeof(PP_FontMetrics_Dev)) - return 0; - memcpy(&object->metrics(), out_metrics.data(), sizeof(PP_FontMetrics_Dev)); - - return PluginResourceTracker::GetInstance()->AddResource(object); -} - -PP_Bool IsFont(PP_Resource resource) { - Font* object = PluginResource::GetAs<Font>(resource); - return BoolToPPBool(!!object); -} - -PP_Bool Describe(PP_Resource font_id, - PP_FontDescription_Dev* description, - PP_FontMetrics_Dev* metrics) { - Font* object = PluginResource::GetAs<Font>(font_id); - if (!object) - return PP_FALSE; - - // Copy the description, the caller expects its face PP_Var to have a ref - // added to it on its behalf. - memcpy(description, &object->desc(), sizeof(PP_FontDescription_Dev)); - PluginVarTracker::GetInstance()->AddRef(description->face); - - memcpy(metrics, &object->metrics(), sizeof(PP_FontMetrics_Dev)); - return PP_TRUE; -} - -PP_Bool DrawTextAt(PP_Resource font_id, - PP_Resource image_data, - const PP_TextRun_Dev* text, - const PP_Point* position, - uint32_t color, - const PP_Rect* clip, - PP_Bool image_data_is_opaque) { - Font* font_object = PluginResource::GetAs<Font>(font_id); - if (!font_object) - return PP_FALSE; - PluginResource* image_object = PluginResourceTracker::GetInstance()-> - GetResourceObject(image_data); - if (!image_object) - return PP_FALSE; - if (font_object->instance() != image_object->instance()) - return PP_FALSE; - - PPBFont_DrawTextAt_Params params; - params.font = font_object->host_resource(); - params.image_data = image_object->host_resource(); - params.text_is_rtl = text->rtl; - params.override_direction = text->override_direction; - params.position = *position; - params.color = color; - if (clip) { - params.clip = *clip; - params.clip_is_null = false; - } else { - params.clip = PP_MakeRectFromXYWH(0, 0, 0, 0); - params.clip_is_null = true; - } - params.image_data_is_opaque = image_data_is_opaque; +bool PPTextRunToTextRun(const PP_TextRun_Dev* run, + WebKitForwarding::Font::TextRun* output) { + const std::string* str = PluginVarTracker::GetInstance()->GetExistingString( + run->text); + if (!str) + return false; - Dispatcher* dispatcher = PluginDispatcher::GetForInstance( - image_object->instance()); - PP_Bool result = PP_FALSE; - if (dispatcher) { - dispatcher->Send(new PpapiHostMsg_PPBFont_DrawTextAt( - INTERFACE_ID_PPB_FONT, - SerializedVarSendInput(dispatcher, text->text), - params, &result)); - } - return result; + output->text = *str; + output->rtl = PPBoolToBool(run->rtl); + output->override_direction = PPBoolToBool(run->override_direction); + return true; } -int32_t MeasureText(PP_Resource font_id, const PP_TextRun_Dev* text) { - Font* object = PluginResource::GetAs<Font>(font_id); - if (!object) - return -1; - - Dispatcher* dispatcher = PluginDispatcher::GetForInstance(object->instance()); - int32_t result = 0; - if (dispatcher) { - dispatcher->Send(new PpapiHostMsg_PPBFont_MeasureText( - INTERFACE_ID_PPB_FONT, object->host_resource(), - SerializedVarSendInput(dispatcher, text->text), - text->rtl, text->override_direction, &result)); - } - return result; -} - -uint32_t CharacterOffsetForPixel(PP_Resource font_id, - const PP_TextRun_Dev* text, - int32_t pixel_position) { - Font* object = PluginResource::GetAs<Font>(font_id); - if (!object) - return -1; - - Dispatcher* dispatcher = PluginDispatcher::GetForInstance(object->instance()); - uint32_t result = 0; - if (dispatcher) { - dispatcher->Send(new PpapiHostMsg_PPBFont_CharacterOffsetForPixel( - INTERFACE_ID_PPB_FONT, object->host_resource(), - SerializedVarSendInput(dispatcher, text->text), - text->rtl, text->override_direction, pixel_position, &result)); - } - return result; -} - -int32_t PixelOffsetForCharacter(PP_Resource font_id, - const PP_TextRun_Dev* text, - uint32_t char_offset) { - Font* object = PluginResource::GetAs<Font>(font_id); - if (!object) - return -1; - - Dispatcher* dispatcher = PluginDispatcher::GetForInstance(object->instance()); - int32_t result = 0; - if (dispatcher) { - dispatcher->Send(new PpapiHostMsg_PPBFont_PixelOffsetForCharacter( - INTERFACE_ID_PPB_FONT, object->host_resource(), - SerializedVarSendInput(dispatcher, text->text), - text->rtl, text->override_direction, char_offset, &result)); - } - return result; -} - -const PPB_Font_Dev font_interface = { - &Create, - &IsFont, - &Describe, - &DrawTextAt, - &MeasureText, - &CharacterOffsetForPixel, - &PixelOffsetForCharacter -}; - InterfaceProxy* CreateFontProxy(Dispatcher* dispatcher, const void* target_interface) { return new PPB_Font_Proxy(dispatcher, target_interface); @@ -219,7 +52,7 @@ PPB_Font_Proxy::~PPB_Font_Proxy() { // static const InterfaceProxy::Info* PPB_Font_Proxy::GetInfo() { static const Info info = { - &font_interface, + ::ppapi::thunk::GetPPB_Font_Thunk(), PPB_FONT_DEV_INTERFACE, INTERFACE_ID_PPB_FONT, false, @@ -229,112 +62,140 @@ const InterfaceProxy::Info* PPB_Font_Proxy::GetInfo() { } bool PPB_Font_Proxy::OnMessageReceived(const IPC::Message& msg) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(PPB_Font_Proxy, msg) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_Create, - OnMsgCreate) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_DrawTextAt, - OnMsgDrawTextAt) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_MeasureText, - OnMsgMeasureText) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_CharacterOffsetForPixel, - OnMsgCharacterOffsetForPixel) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_PixelOffsetForCharacter, - OnMsgPixelOffsetForCharacter) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; + // There aren't any font messages. + NOTREACHED(); + return false; } -void PPB_Font_Proxy::OnMsgCreate( - PP_Instance instance, - const SerializedFontDescription& in_description, - HostResource* result, - SerializedFontDescription* out_description, - std::string* out_metrics) { - // Convert the face name in the input description. - PP_FontDescription_Dev in_pp_desc; - in_description.SetToPPFontDescription(dispatcher(), &in_pp_desc, false); +Font::Font(const HostResource& resource, + const PP_FontDescription_Dev& desc) + : PluginResource(resource), + webkit_event_(false, false) { + const std::string* face = PluginVarTracker::GetInstance()->GetExistingString( + desc.face); - // Make sure the output is always defined so we can still serialize it back - // to the plugin below. - PP_FontDescription_Dev out_pp_desc; - memset(&out_pp_desc, 0, sizeof(PP_FontDescription_Dev)); - out_pp_desc.face = PP_MakeUndefined(); + WebKitForwarding* forwarding = GetDispatcher()->GetWebKitForwarding(); - result->SetHostResource(instance, - ppb_font_target()->Create(instance, &in_pp_desc)); - if (!result->is_null()) { - // Get the metrics and resulting description to return to the browser. - PP_FontMetrics_Dev metrics; - if (ppb_font_target()->Describe(result->host_resource(), &out_pp_desc, - &metrics)) { - out_metrics->assign(reinterpret_cast<const char*>(&metrics), - sizeof(PP_FontMetrics_Dev)); - } - } + WebKitForwarding::Font* result = NULL; + RunOnWebKitThread(base::Bind(&WebKitForwarding::CreateFontForwarding, + base::Unretained(forwarding), + &webkit_event_, desc, + face ? *face : std::string(), &result)); + font_forwarding_.reset(result); +} - // This must always get called or it will assert when trying to serialize - // the un-filled-in SerializedFontDescription as the return value. - out_description->SetFromPPFontDescription(dispatcher(), out_pp_desc, false); +Font::~Font() { } -void PPB_Font_Proxy::OnMsgDrawTextAt(SerializedVarReceiveInput text, - const PPBFont_DrawTextAt_Params& params, - PP_Bool* result) { - PP_TextRun_Dev run; - run.text = text.Get(dispatcher()); - run.rtl = params.text_is_rtl; - run.override_direction = params.override_direction; +ppapi::thunk::PPB_Font_API* Font::AsFont_API() { + return this; +} - *result = ppb_font_target()->DrawTextAt(params.font.host_resource(), - params.image_data.host_resource(), &run, ¶ms.position, params.color, - params.clip_is_null ? NULL : ¶ms.clip, params.image_data_is_opaque); +Font* Font::AsFont() { + return this; } -void PPB_Font_Proxy::OnMsgMeasureText(HostResource font, - SerializedVarReceiveInput text, - PP_Bool text_is_rtl, - PP_Bool override_direction, - int32_t* result) { - PP_TextRun_Dev run; - run.text = text.Get(dispatcher()); - run.rtl = text_is_rtl; - run.override_direction = override_direction; +PP_Bool Font::Describe(PP_FontDescription_Dev* description, + PP_FontMetrics_Dev* metrics) { + std::string face; + PP_Bool result = PP_FALSE; + RunOnWebKitThread(base::Bind(&WebKitForwarding::Font::Describe, + base::Unretained(font_forwarding_.get()), + &webkit_event_, description, &face, metrics, + &result)); + + if (result == PP_TRUE) { + description->face.type = PP_VARTYPE_STRING; + description->face.value.as_id = + PluginVarTracker::GetInstance()->MakeString(face); + } else { + description->face.type = PP_VARTYPE_UNDEFINED; + } + return result; +} + +PP_Bool Font::DrawTextAt(PP_Resource pp_image_data, + const PP_TextRun_Dev* text, + const PP_Point* position, + uint32_t color, + const PP_Rect* clip, + PP_Bool image_data_is_opaque) { + // Convert to an ImageData object. + ppapi::shared_impl::ResourceObjectBase* image_base = + ppapi::shared_impl::TrackerBase::Get()->GetResourceAPI(pp_image_data); + if (!image_base) + return PP_FALSE; + PPB_ImageData_API* image_api = image_base->GetAs<PPB_ImageData_API>(); + if (!image_api) + return PP_FALSE; + ImageData* image_data = static_cast<ImageData*>(image_api); + + skia::PlatformCanvas* canvas = image_data->mapped_canvas(); + bool needs_unmapping = false; + if (!canvas) { + needs_unmapping = true; + image_data->Map(); + canvas = image_data->mapped_canvas(); + if (!canvas) + return PP_FALSE; // Failure mapping. + } - *result = ppb_font_target()->MeasureText(font.host_resource(), &run); + WebKitForwarding::Font::TextRun run; + if (!PPTextRunToTextRun(text, &run)) { + if (needs_unmapping) + image_data->Unmap(); + return PP_FALSE; + } + RunOnWebKitThread(base::Bind( + &WebKitForwarding::Font::DrawTextAt, + base::Unretained(font_forwarding_.get()), + &webkit_event_, + WebKitForwarding::Font::DrawTextParams(canvas, run, position, color, + clip, image_data_is_opaque))); + + if (needs_unmapping) + image_data->Unmap(); + return PP_TRUE; } -void PPB_Font_Proxy::OnMsgCharacterOffsetForPixel( - HostResource font, - SerializedVarReceiveInput text, - PP_Bool text_is_rtl, - PP_Bool override_direction, - int32_t pixel_pos, - uint32_t* result) { - PP_TextRun_Dev run; - run.text = text.Get(dispatcher()); - run.rtl = text_is_rtl; - run.override_direction = override_direction; +int32_t Font::MeasureText(const PP_TextRun_Dev* text) { + WebKitForwarding::Font::TextRun run; + if (!PPTextRunToTextRun(text, &run)) + return -1; + int32_t result = -1; + RunOnWebKitThread(base::Bind(&WebKitForwarding::Font::MeasureText, + base::Unretained(font_forwarding_.get()), + &webkit_event_, run, &result)); + return result; +} - *result = ppb_font_target()->CharacterOffsetForPixel(font.host_resource(), - &run, pixel_pos); +uint32_t Font::CharacterOffsetForPixel(const PP_TextRun_Dev* text, + int32_t pixel_position) { + WebKitForwarding::Font::TextRun run; + if (!PPTextRunToTextRun(text, &run)) + return -1; + uint32_t result = -1; + RunOnWebKitThread(base::Bind(&WebKitForwarding::Font::CharacterOffsetForPixel, + base::Unretained(font_forwarding_.get()), + &webkit_event_, run, pixel_position, &result)); + return result; } -void PPB_Font_Proxy::OnMsgPixelOffsetForCharacter( - HostResource font, - SerializedVarReceiveInput text, - PP_Bool text_is_rtl, - PP_Bool override_direction, - uint32_t char_offset, - int32_t* result) { - PP_TextRun_Dev run; - run.text = text.Get(dispatcher()); - run.rtl = text_is_rtl; - run.override_direction = override_direction; +int32_t Font::PixelOffsetForCharacter(const PP_TextRun_Dev* text, + uint32_t char_offset) { + WebKitForwarding::Font::TextRun run; + if (!PPTextRunToTextRun(text, &run)) + return -1; + int32_t result = -1; + RunOnWebKitThread(base::Bind(&WebKitForwarding::Font::PixelOffsetForCharacter, + base::Unretained(font_forwarding_.get()), + &webkit_event_, run, char_offset, &result)); + return result; +} - *result = ppb_font_target()->PixelOffsetForCharacter(font.host_resource(), - &run, char_offset); +void Font::RunOnWebKitThread(const base::Closure& task) { + GetDispatcher()->PostToWebKitThread(FROM_HERE, task); + webkit_event_.Wait(); } } // namespace proxy diff --git a/ppapi/proxy/ppb_font_proxy.h b/ppapi/proxy/ppb_font_proxy.h index 40f53d6..35b1c55 100644 --- a/ppapi/proxy/ppb_font_proxy.h +++ b/ppapi/proxy/ppb_font_proxy.h @@ -6,18 +6,18 @@ #define PPAPI_PROXY_PPB_FONT_PROXY_H_ #include "base/basictypes.h" -#include "ppapi/c/pp_instance.h" -#include "ppapi/c/pp_resource.h" +#include "base/synchronization/waitable_event.h" #include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/interface_proxy.h" +#include "ppapi/proxy/plugin_resource.h" +#include "ppapi/shared_impl/webkit_forwarding.h" +#include "ppapi/thunk/ppb_font_api.h" struct PPB_Font_Dev; namespace pp { namespace proxy { -struct PPBFont_DrawTextAt_Params; -struct SerializedFontDescription; class SerializedVarReceiveInput; class PPB_Font_Proxy : public InterfaceProxy { @@ -27,44 +27,57 @@ class PPB_Font_Proxy : public InterfaceProxy { static const Info* GetInfo(); - const PPB_Font_Dev* ppb_font_target() const { - return static_cast<const PPB_Font_Dev*>(target_interface()); - } - // InterfaceProxy implementation. virtual bool OnMessageReceived(const IPC::Message& msg); private: - // Message handlers. - void OnMsgCreate(PP_Instance instance, - const SerializedFontDescription& in_description, - HostResource* result, - SerializedFontDescription* out_description, - std::string* out_metrics); - void OnMsgDrawTextAt(SerializedVarReceiveInput text, - const PPBFont_DrawTextAt_Params& params, - PP_Bool* result); - void OnMsgMeasureText(HostResource font, - SerializedVarReceiveInput text, - PP_Bool text_is_rtl, - PP_Bool override_direction, - int32_t* result); - void OnMsgCharacterOffsetForPixel(HostResource font, - SerializedVarReceiveInput text, - PP_Bool text_is_rtl, - PP_Bool override_direction, - int32_t pixel_pos, - uint32_t* result); - void OnMsgPixelOffsetForCharacter(HostResource font, - SerializedVarReceiveInput text, - PP_Bool text_is_rtl, - PP_Bool override_direction, - uint32_t char_offset, - int32_t* result); - DISALLOW_COPY_AND_ASSIGN(PPB_Font_Proxy); }; +class Font : public PluginResource, + public ppapi::thunk::PPB_Font_API { + public: + // Note that there isn't a "real" resource in the renderer backing a font, + // it lives entirely in the plugin process. So the resource ID in the host + // resource should be 0. However, various code assumes the instance in the + // host resource is valid (this is how resources are associated with + // instances), so that should be set. + Font(const HostResource& resource, const PP_FontDescription_Dev& desc); + virtual ~Font(); + + // ResourceObjectBase. + virtual ppapi::thunk::PPB_Font_API* AsFont_API() OVERRIDE; + + // PluginResource overrides. + virtual Font* AsFont() OVERRIDE; + + // PPB_Font_API implementation. + virtual PP_Bool Describe(PP_FontDescription_Dev* description, + PP_FontMetrics_Dev* metrics) OVERRIDE; + virtual PP_Bool DrawTextAt(PP_Resource image_data, + const PP_TextRun_Dev* text, + const PP_Point* position, + uint32_t color, + const PP_Rect* clip, + PP_Bool image_data_is_opaque) OVERRIDE; + virtual int32_t MeasureText(const PP_TextRun_Dev* text) OVERRIDE; + virtual uint32_t CharacterOffsetForPixel(const PP_TextRun_Dev* text, + int32_t pixel_position) OVERRIDE; + virtual int32_t PixelOffsetForCharacter(const PP_TextRun_Dev* text, + uint32_t char_offset) OVERRIDE; + + private: + // Posts the given closure to the WebKit thread and waits on the + // webkit_event_ for the task to continue. + void RunOnWebKitThread(const base::Closure& task); + + base::WaitableEvent webkit_event_; + + scoped_ptr<pp::shared_impl::WebKitForwarding::Font> font_forwarding_; + + DISALLOW_COPY_AND_ASSIGN(Font); +}; + } // namespace proxy } // namespace pp diff --git a/ppapi/proxy/ppb_image_data_proxy.cc b/ppapi/proxy/ppb_image_data_proxy.cc index ebb1d19..767190b 100644 --- a/ppapi/proxy/ppb_image_data_proxy.cc +++ b/ppapi/proxy/ppb_image_data_proxy.cc @@ -18,15 +18,8 @@ #include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/thunk/thunk.h" - -#if defined(OS_LINUX) -#include <sys/shm.h> -#elif defined(OS_MACOSX) -#include <sys/stat.h> -#include <sys/mman.h> -#elif defined(OS_WIN) -#include <windows.h> -#endif +#include "skia/ext/platform_canvas.h" +#include "ui/gfx/surface/transport_dib.h" namespace pp { namespace proxy { @@ -72,13 +65,15 @@ ImageData::ImageData(const HostResource& resource, const PP_ImageDataDesc& desc, ImageHandle handle) : PluginResource(resource), - desc_(desc), - handle_(handle), - mapped_data_(NULL) { + desc_(desc) { +#if defined(OS_WIN) + transport_dib_.reset(TransportDIB::CreateWithHandle(handle)); +#else + transport_dib_.reset(TransportDIB::Map(handle)); +#endif } ImageData::~ImageData() { - Unmap(); } ::ppapi::thunk::PPB_ImageData_API* ImageData::AsImageData_API() { @@ -95,47 +90,23 @@ PP_Bool ImageData::Describe(PP_ImageDataDesc* desc) { } void* ImageData::Map() { -#if defined(OS_WIN) - mapped_data_ = ::MapViewOfFile(handle_, FILE_MAP_READ | FILE_MAP_WRITE, - 0, 0, 0); - return mapped_data_; -#elif defined(OS_MACOSX) - struct stat st; - if (fstat(handle_.fd, &st) != 0) - return NULL; - void* memory = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, - MAP_SHARED, handle_.fd, 0); - if (memory == MAP_FAILED) - return NULL; - mapped_data_ = memory; - return mapped_data_; -#else - int shmkey = handle_; - void* address = shmat(shmkey, NULL, 0); - // Mark for deletion in case we crash so the kernel will clean it up. - shmctl(shmkey, IPC_RMID, 0); - if (address == (void*)-1) - return NULL; - mapped_data_ = address; - return address; -#endif + if (!mapped_canvas_.get()) { + mapped_canvas_.reset(transport_dib_->GetPlatformCanvas(desc_.size.width, + desc_.size.height)); + if (!mapped_canvas_.get()) + return NULL; + } + const SkBitmap& bitmap = + mapped_canvas_->getTopPlatformDevice().accessBitmap(true); + + bitmap.lockPixels(); + return bitmap.getAddr(0, 0); } void ImageData::Unmap() { -#if defined(OS_WIN) - if (mapped_data_) - ::UnmapViewOfFile(mapped_data_); -#elif defined(OS_MACOSX) - if (mapped_data_) { - struct stat st; - if (fstat(handle_.fd, &st) == 0) - munmap(mapped_data_, st.st_size); - } -#else - if (mapped_data_) - shmdt(mapped_data_); -#endif - mapped_data_ = NULL; + // TODO(brettw) have a way to unmap a TransportDIB. Currently this isn't + // possible since deleting the TransportDIB also frees all the handles. + // We need to add a method to TransportDIB to release the handles. } #if defined(OS_WIN) diff --git a/ppapi/proxy/ppb_image_data_proxy.h b/ppapi/proxy/ppb_image_data_proxy.h index 8a3bce2..71198bd 100644 --- a/ppapi/proxy/ppb_image_data_proxy.h +++ b/ppapi/proxy/ppb_image_data_proxy.h @@ -19,6 +19,11 @@ #include "ppapi/thunk/ppb_image_data_api.h" struct PPB_ImageData; +class TransportDIB; + +namespace skia { +class PlatformCanvas; +} namespace pp { namespace proxy { @@ -60,6 +65,8 @@ class ImageData : public PluginResource, virtual void* Map(); virtual void Unmap(); + skia::PlatformCanvas* mapped_canvas() const { return mapped_canvas_.get(); } + const PP_ImageDataDesc& desc() const { return desc_; } static const ImageHandle NullHandle; @@ -67,9 +74,11 @@ class ImageData : public PluginResource, private: PP_ImageDataDesc desc_; - ImageHandle handle_; - void* mapped_data_; + scoped_ptr<TransportDIB> transport_dib_; + + // Null when the image isn't mapped. + scoped_ptr<skia::PlatformCanvas> mapped_canvas_; DISALLOW_COPY_AND_ASSIGN(ImageData); }; diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc index 39c9c11..7346add 100644 --- a/ppapi/proxy/resource_creation_proxy.cc +++ b/ppapi/proxy/resource_creation_proxy.cc @@ -12,8 +12,10 @@ #include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppb_graphics_2d_proxy.h" +#include "ppapi/proxy/ppb_font_proxy.h" #include "ppapi/proxy/ppb_image_data_proxy.h" #include "ppapi/c/trusted/ppb_image_data_trusted.h" +#include "ppapi/shared_impl/font_impl.h" #include "ppapi/shared_impl/function_group_base.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/ppb_image_data_api.h" @@ -35,6 +37,20 @@ ResourceCreationProxy::AsResourceCreation() { return this; } +PP_Resource ResourceCreationProxy::CreateFontObject( + PP_Instance instance, + const PP_FontDescription_Dev* description) { + if (!pp::shared_impl::FontImpl::IsPPFontDescriptionValid(*description)) + return 0; + + // See the comment above Font's constructor for why we do this. + HostResource resource; + resource.SetHostResource(instance, 0); + + linked_ptr<Font> object(new Font(resource, *description)); + return PluginResourceTracker::GetInstance()->AddResource(object); +} + PP_Resource ResourceCreationProxy::CreateGraphics2D(PP_Instance pp_instance, const PP_Size& size, PP_Bool is_always_opaque) { @@ -127,10 +143,10 @@ void ResourceCreationProxy::OnMsgCreateImageData( result->SetHostResource(instance, resource); // Get the description, it's just serialized as a string. - ppapi::thunk::EnterResource<ppapi::thunk::PPB_ImageData_API> - enter_resource(resource, false); + ppapi::thunk::EnterResource<ppapi::thunk::PPB_ImageData_API> enter_resource( + resource, false); PP_ImageDataDesc desc; - if (enter_resource.object()->Describe(&desc)) { + if (enter_resource.object()->Describe(&desc) == PP_TRUE) { image_data_desc->resize(sizeof(PP_ImageDataDesc)); memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc)); } diff --git a/ppapi/proxy/resource_creation_proxy.h b/ppapi/proxy/resource_creation_proxy.h index 898c16e..4cc1391 100644 --- a/ppapi/proxy/resource_creation_proxy.h +++ b/ppapi/proxy/resource_creation_proxy.h @@ -32,6 +32,9 @@ class ResourceCreationProxy : public ::ppapi::shared_impl::FunctionGroupBase, virtual ::ppapi::thunk::ResourceCreationAPI* AsResourceCreation(); // ResourceCreationAPI (called in plugin). + virtual PP_Resource CreateFontObject( + PP_Instance instance, + const PP_FontDescription_Dev* description); virtual PP_Resource CreateGraphics2D(PP_Instance pp_instance, const PP_Size& size, PP_Bool is_always_opaque); diff --git a/ppapi/proxy/serialized_structs.h b/ppapi/proxy/serialized_structs.h index 1482ab3..1330f72 100644 --- a/ppapi/proxy/serialized_structs.h +++ b/ppapi/proxy/serialized_structs.h @@ -81,22 +81,6 @@ struct PPBFileRef_CreateInfo { SerializedVar name; }; -// Since there are so many parameters, DrawTextAt requires this separate -// structure. This includes everything but the font name. Because the font name -// is a var, it's much more convenient to use the normal way of passing a -// PP_Var. -struct PPBFont_DrawTextAt_Params { - HostResource font; - HostResource image_data; - PP_Bool text_is_rtl; - PP_Bool override_direction; - PP_Point position; - uint32_t color; - PP_Rect clip; - bool clip_is_null; - PP_Bool image_data_is_opaque; -}; - struct PPBFlash_DrawGlyphs_Params { PPBFlash_DrawGlyphs_Params(); ~PPBFlash_DrawGlyphs_Params(); diff --git a/ppapi/shared_impl/DEPS b/ppapi/shared_impl/DEPS index ebb73ea..512b07b 100644 --- a/ppapi/shared_impl/DEPS +++ b/ppapi/shared_impl/DEPS @@ -1,13 +1,11 @@ include_rules = [ "+base", + "+skia", + "+webkit/glue", # Since this is used by the implementation in /webkit, we don't want it to # depend on IPC. "-ipc", "-ppapi/cpp", - - # The image data implementation depends on how we're building Skia. This isn't - # a link-time dependency, so it's OK. - "+skia/config/SkUserConfig.h" ] diff --git a/ppapi/shared_impl/font_impl.cc b/ppapi/shared_impl/font_impl.cc new file mode 100644 index 0000000..3feaf9f --- /dev/null +++ b/ppapi/shared_impl/font_impl.cc @@ -0,0 +1,36 @@ +// Copyright (c) 2011 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 "ppapi/shared_impl/font_impl.h" + +#include "ppapi/c/dev/ppb_font_dev.h" + +namespace pp { +namespace shared_impl { + +// static +bool FontImpl::IsPPFontDescriptionValid(const PP_FontDescription_Dev& desc) { + // Check validity of string. We can't check the actual text since we could + // be on the wrong thread and don't know if we're in the plugin or the host. + if (desc.face.type != PP_VARTYPE_STRING && + desc.face.type != PP_VARTYPE_UNDEFINED) + return false; + + // Check enum ranges. + if (static_cast<int>(desc.family) < PP_FONTFAMILY_DEFAULT || + static_cast<int>(desc.family) > PP_FONTFAMILY_MONOSPACE) + return false; + if (static_cast<int>(desc.weight) < PP_FONTWEIGHT_100 || + static_cast<int>(desc.weight) > PP_FONTWEIGHT_900) + return false; + + // Check for excessive sizes which may cause layout to get confused. + if (desc.size > 200) + return false; + + return true; +} + +} // namespace shared_impl +} // namespace pp diff --git a/ppapi/shared_impl/font_impl.h b/ppapi/shared_impl/font_impl.h new file mode 100644 index 0000000..ebdf38a --- /dev/null +++ b/ppapi/shared_impl/font_impl.h @@ -0,0 +1,33 @@ +// Copyright (c) 2011 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. + +#ifndef PPAPI_SHARED_IMPL_FONT_IMPL_H_ +#define PPAPI_SHARED_IMPL_FONT_IMPL_H_ +#pragma once + +#include <string> + +#include "base/basictypes.h" +#include "base/scoped_ptr.h" +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_stdint.h" + +struct PP_FontDescription_Dev; + +namespace pp { +namespace shared_impl { + +class FontImpl { + public: + // Validates the parameters in thee description. Can be called on any thread. + static bool IsPPFontDescriptionValid(const PP_FontDescription_Dev& desc); + + private: + DISALLOW_COPY_AND_ASSIGN(FontImpl); +}; + +} // namespace shared_impl +} // namespace pp + +#endif // PPAPI_SHARED_IMPL_FONT_IMPL_H_ diff --git a/ppapi/shared_impl/resource_object_base.h b/ppapi/shared_impl/resource_object_base.h index 50ba30d..1a87360 100644 --- a/ppapi/shared_impl/resource_object_base.h +++ b/ppapi/shared_impl/resource_object_base.h @@ -8,6 +8,7 @@ namespace ppapi { namespace thunk { +class PPB_Font_API; class PPB_Graphics2D_API; class PPB_ImageData_API; } @@ -17,6 +18,7 @@ namespace shared_impl { class ResourceObjectBase { public: + virtual thunk::PPB_Font_API* AsFont_API() { return NULL; } virtual thunk::PPB_Graphics2D_API* AsGraphics2D_API() { return NULL; } virtual thunk::PPB_ImageData_API* AsImageData_API() { return NULL; } @@ -24,6 +26,10 @@ class ResourceObjectBase { }; template<> +inline thunk::PPB_Font_API* ResourceObjectBase::GetAs() { + return AsFont_API(); +} +template<> inline thunk::PPB_Graphics2D_API* ResourceObjectBase::GetAs() { return AsGraphics2D_API(); } diff --git a/ppapi/shared_impl/webkit_forwarding.cc b/ppapi/shared_impl/webkit_forwarding.cc new file mode 100644 index 0000000..02573f8 --- /dev/null +++ b/ppapi/shared_impl/webkit_forwarding.cc @@ -0,0 +1,36 @@ +// Copyright (c) 2011 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 "ppapi/shared_impl/webkit_forwarding.h" + +namespace pp { +namespace shared_impl { + +WebKitForwarding::Font::DrawTextParams::DrawTextParams( + skia::PlatformCanvas* destination_arg, + const TextRun& text_arg, + const PP_Point* position_arg, + uint32_t color_arg, + const PP_Rect* clip_arg, + PP_Bool image_data_is_opaque_arg) + : destination(destination_arg), + text(text_arg), + position(position_arg), + color(color_arg), + clip(clip_arg), + image_data_is_opaque(image_data_is_opaque_arg) { +} + +WebKitForwarding::Font::DrawTextParams::~DrawTextParams() { +} + +WebKitForwarding::Font::~Font() { +} + +WebKitForwarding::~WebKitForwarding() { +} + +} // namespace shared_impl +} // namespace pp + diff --git a/ppapi/shared_impl/webkit_forwarding.h b/ppapi/shared_impl/webkit_forwarding.h new file mode 100644 index 0000000..aa788f8 --- /dev/null +++ b/ppapi/shared_impl/webkit_forwarding.h @@ -0,0 +1,104 @@ +// Copyright (c) 2011 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. + +#ifndef PPAPI_SHARED_IMPL_WEBKIT_FORWARDING_H_ +#define PPAPI_SHARED_IMPL_WEBKIT_FORWARDING_H_ + +#include <string> + +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_stdint.h" + +struct PP_FontDescription_Dev; +struct PP_FontMetrics_Dev; +struct PP_Point; +struct PP_Rect; + +namespace base { +class WaitableEvent; +} + +namespace skia { +class PlatformCanvas; +} + +namespace pp { +namespace shared_impl { + +class WebKitForwarding { + public: + class Font { + public: + // C++ version of PP_TextRun_Dev. Since the functions below will be called + // on an alternate thread in the proxy, and since there are different + // methods of converting PP_Var -> strings in the plugin and the proxy, we + // can't use PP_Vars in the Do* functions below. + struct TextRun { + std::string text; + bool rtl; + bool override_direction; + }; + + // DoDrawText takes too many arguments to be used with base::Bind, so we + // use this struct to hold them. + struct DrawTextParams { + DrawTextParams(skia::PlatformCanvas* destination_arg, + const TextRun& text_arg, + const PP_Point* position_arg, + uint32_t color_arg, + const PP_Rect* clip_arg, + PP_Bool image_data_is_opaque_arg); + ~DrawTextParams(); + + skia::PlatformCanvas* destination; + const TextRun& text; + const PP_Point* position; + uint32_t color; + const PP_Rect* clip; + PP_Bool image_data_is_opaque; + }; + + virtual ~Font(); + + // The face name in the description is not filled in to avoid a dependency + // on creating vars. Instead, the face name is placed into the given + // string. See class description for waitable_event documentation. If + // non-null, the given event will be set on completion. + virtual void Describe(base::WaitableEvent* event, + PP_FontDescription_Dev* description, + std::string* face, + PP_FontMetrics_Dev* metrics, + PP_Bool* result) = 0; + virtual void DrawTextAt(base::WaitableEvent* event, + const DrawTextParams& params) = 0; + virtual void MeasureText(base::WaitableEvent* event, + const TextRun& text, + int32_t* result) = 0; + virtual void CharacterOffsetForPixel(base::WaitableEvent* event, + const TextRun& text, + int32_t pixel_position, + uint32_t* result) = 0; + virtual void PixelOffsetForCharacter(base::WaitableEvent* event, + const TextRun& text, + uint32_t char_offset, + int32_t* result) = 0; + }; + + virtual ~WebKitForwarding(); + + // Creates a new font with the given description. The desc_face is the face + // name already extracted from the description. The caller owns the result + // pointer, which will never be NULL. If non-null, the given event will be + // set on completion. + virtual void CreateFontForwarding(base::WaitableEvent* event, + const PP_FontDescription_Dev& desc, + const std::string& desc_face, + Font** result) = 0; + +}; + +} // namespace shared_impl +} // namespace pp + +#endif // PPAPI_SHARED_IMPL_WEBKIT_FORWARDING_H_ diff --git a/ppapi/tests/test_url_loader.cc b/ppapi/tests/test_url_loader.cc index 55bd851..f559507 100644 --- a/ppapi/tests/test_url_loader.cc +++ b/ppapi/tests/test_url_loader.cc @@ -221,7 +221,6 @@ std::string TestURLLoader::TestStreamToFile() { if (rv != PP_OK) return ReportError("URLLoader::FinishStreamingToFile", rv); - pp::FileIO_Dev reader(instance_); rv = reader.Open(body, PP_FILEOPENFLAG_READ, callback); if (rv == PP_OK_COMPLETIONPENDING) diff --git a/ppapi/thunk/ppb_font_api.h b/ppapi/thunk/ppb_font_api.h new file mode 100644 index 0000000..b711545 --- /dev/null +++ b/ppapi/thunk/ppb_font_api.h @@ -0,0 +1,33 @@ +// Copyright (c) 2011 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. + +#ifndef PPAPI_THUNK_PPB_FONT_API_H_ +#define PPAPI_THUNK_PPB_FONT_API_H_ + +#include "ppapi/c/dev/ppb_font_dev.h" + +namespace ppapi { +namespace thunk { + +class PPB_Font_API { + public: + virtual PP_Bool Describe(PP_FontDescription_Dev* description, + PP_FontMetrics_Dev* metrics) = 0; + virtual PP_Bool DrawTextAt(PP_Resource image_data, + const PP_TextRun_Dev* text, + const PP_Point* position, + uint32_t color, + const PP_Rect* clip, + PP_Bool image_data_is_opaque) = 0; + virtual int32_t MeasureText(const PP_TextRun_Dev* text) = 0; + virtual uint32_t CharacterOffsetForPixel(const PP_TextRun_Dev* text, + int32_t pixel_position) = 0; + virtual int32_t PixelOffsetForCharacter(const PP_TextRun_Dev* text, + uint32_t char_offset) = 0; +}; + +} // namespace thunk +} // namespace ppapi + +#endif // PPAPI_THUNK_PPB_FONT_API_H_ diff --git a/ppapi/thunk/ppb_font_thunk.cc b/ppapi/thunk/ppb_font_thunk.cc new file mode 100644 index 0000000..eac573e --- /dev/null +++ b/ppapi/thunk/ppb_font_thunk.cc @@ -0,0 +1,93 @@ +// Copyright (c) 2011 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 "ppapi/thunk/thunk.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_font_api.h" +#include "ppapi/thunk/resource_creation_api.h" + +namespace ppapi { +namespace thunk { + +namespace { + +PP_Resource Create(PP_Instance instance, + const PP_FontDescription_Dev* description) { + EnterFunction<ResourceCreationAPI> enter(instance, true); + if (enter.failed()) + return 0; + return enter.functions()->CreateFontObject(instance, description); +} + +PP_Bool IsFont(PP_Resource resource) { + EnterResource<PPB_Font_API> enter(resource, false); + return enter.succeeded() ? PP_TRUE : PP_FALSE; +} + +PP_Bool Describe(PP_Resource font_id, + PP_FontDescription_Dev* description, + PP_FontMetrics_Dev* metrics) { + EnterResource<PPB_Font_API> enter(font_id, true); + if (enter.failed()) + return PP_FALSE; + return enter.object()->Describe(description, metrics); +} + +PP_Bool DrawTextAt(PP_Resource font_id, + PP_Resource image_data, + const PP_TextRun_Dev* text, + const PP_Point* position, + uint32_t color, + const PP_Rect* clip, + PP_Bool image_data_is_opaque) { + EnterResource<PPB_Font_API> enter(font_id, true); + if (enter.failed()) + return PP_FALSE; + return enter.object()->DrawTextAt(image_data, text, position, color, clip, + image_data_is_opaque); +} + +int32_t MeasureText(PP_Resource font_id, const PP_TextRun_Dev* text) { + EnterResource<PPB_Font_API> enter(font_id, true); + if (enter.failed()) + return -1; + return enter.object()->MeasureText(text); +} + +uint32_t CharacterOffsetForPixel(PP_Resource font_id, + const PP_TextRun_Dev* text, + int32_t pixel_position) { + EnterResource<PPB_Font_API> enter(font_id, true); + if (enter.failed()) + return -1; + return enter.object()->CharacterOffsetForPixel(text, pixel_position); +} + +int32_t PixelOffsetForCharacter(PP_Resource font_id, + const PP_TextRun_Dev* text, + uint32_t char_offset) { + EnterResource<PPB_Font_API> enter(font_id, true); + if (enter.failed()) + return -1; + return enter.object()->PixelOffsetForCharacter(text, char_offset); +} + +const PPB_Font_Dev g_ppb_font_thunk = { + &Create, + &IsFont, + &Describe, + &DrawTextAt, + &MeasureText, + &CharacterOffsetForPixel, + &PixelOffsetForCharacter +}; + +} // namespace + +const PPB_Font_Dev* GetPPB_Font_Thunk() { + return &g_ppb_font_thunk; +} + +} // namespace thunk +} // namespace ppapi diff --git a/ppapi/thunk/ppb_image_data_api.h b/ppapi/thunk/ppb_image_data_api.h index 6cfbc43..cce38b29 100644 --- a/ppapi/thunk/ppb_image_data_api.h +++ b/ppapi/thunk/ppb_image_data_api.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef PPAPI_THUNK_IMAGE_DATA_API_H_ -#define PPAPI_THUNK_IMAGE_DATA_API_H_ +#ifndef PPAPI_THUNK_PPB_IMAGE_DATA_API_H_ +#define PPAPI_THUNK_PPB_IMAGE_DATA_API_H_ #include "ppapi/c/pp_bool.h" #include "ppapi/c/ppb_image_data.h" @@ -21,4 +21,4 @@ class PPB_ImageData_API { } // namespace thunk } // namespace ppapi -#endif // PPAPI_THUNK_IMAGE_DATA_API_H_ +#endif // PPAPI_THUNK_PPB_IMAGE_DATA_API_H_ diff --git a/ppapi/thunk/resource_creation_api.h b/ppapi/thunk/resource_creation_api.h index bb81776..c6561b9 100644 --- a/ppapi/thunk/resource_creation_api.h +++ b/ppapi/thunk/resource_creation_api.h @@ -11,6 +11,7 @@ #include "ppapi/c/ppb_image_data.h" #include "ppapi/proxy/interface_id.h" +struct PP_FontDescription_Dev; struct PP_Size; namespace ppapi { @@ -26,6 +27,10 @@ class ResourceCreationAPI { static const ::pp::proxy::InterfaceID interface_id = ::pp::proxy::INTERFACE_ID_RESOURCE_CREATION; + // Note: can't be called CreateFont due to Windows #defines. + virtual PP_Resource CreateFontObject( + PP_Instance instance, + const PP_FontDescription_Dev* description) = 0; virtual PP_Resource CreateGraphics2D(PP_Instance instance, const PP_Size& size, PP_Bool is_always_opaque) = 0; diff --git a/ppapi/thunk/thunk.h b/ppapi/thunk/thunk.h index 39ae8f9..49bb515 100644 --- a/ppapi/thunk/thunk.h +++ b/ppapi/thunk/thunk.h @@ -7,12 +7,14 @@ #include "base/synchronization/lock.h" +struct PPB_Font_Dev; struct PPB_Graphics2D; struct PPB_ImageData; namespace ppapi { namespace thunk { +const PPB_Font_Dev* GetPPB_Font_Thunk(); const PPB_Graphics2D* GetPPB_Graphics2D_Thunk(); const PPB_ImageData* GetPPB_ImageData_Thunk(); |