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 | |
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
68 files changed, 1585 insertions, 784 deletions
diff --git a/base/bind_helpers.h b/base/bind_helpers.h index 27434e0..73fd81e 100644 --- a/base/bind_helpers.h +++ b/base/bind_helpers.h @@ -123,6 +123,9 @@ namespace internal { // // TODO(ajwong): Move to ref_counted.h or template_util.h when we've vetted // this works well. +// +// TODO(ajwong): Make this check for Release() as well. +// See http://crbug.com/82038. template <typename T> class SupportsAddRefAndRelease { typedef char Yes[1]; @@ -130,7 +133,6 @@ class SupportsAddRefAndRelease { struct BaseMixin { void AddRef(); - void Release(); }; // MSVC warns when you try to use Base if T has a private destructor, the @@ -148,13 +150,13 @@ class SupportsAddRefAndRelease { template <void(BaseMixin::*)(void)> struct Helper {}; template <typename C> - static No& Check(Helper<&C::AddRef>*, Helper<&C::Release>*); + static No& Check(Helper<&C::AddRef>*); template <typename > static Yes& Check(...); public: - static const bool value = sizeof(Check<Base>(0,0)) == sizeof(Yes); + static const bool value = sizeof(Check<Base>(0)) == sizeof(Yes); }; diff --git a/build/all.gyp b/build/all.gyp index 4258761..8da3952 100644 --- a/build/all.gyp +++ b/build/all.gyp @@ -22,6 +22,7 @@ '../media/media.gyp:*', '../net/net.gyp:*', '../ppapi/ppapi.gyp:*', + '../ppapi/ppapi_internal.gyp:*', '../printing/printing.gyp:*', '../sdch/sdch.gyp:*', '../skia/skia.gyp:*', diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 087e0fb..ef91d7e 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -1308,6 +1308,7 @@ '../media/media.gyp:*', '../net/net.gyp:*', '../ppapi/ppapi.gyp:*', + '../ppapi/ppapi_internal.gyp:*', '../printing/printing.gyp:*', '../sdch/sdch.gyp:*', '../skia/skia.gyp:*', diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index dec0729..26895f9 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -32,7 +32,7 @@ '../content/content.gyp:content_browser', '../crypto/crypto.gyp:crypto', '../media/media.gyp:media', - '../ppapi/ppapi.gyp:ppapi_proxy', # For PpapiMsg_LoadPlugin + '../ppapi/ppapi_internal.gyp:ppapi_proxy', # For PpapiMsg_LoadPlugin '../printing/printing.gyp:printing', '../skia/skia.gyp:skia', '../third_party/bzip2/bzip2.gyp:bzip2', diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index 7c43d77..b094911 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi @@ -16,7 +16,7 @@ 'safe_browsing_proto', '../content/content.gyp:content_renderer', '../content/content.gyp:content_plugin', - '../ppapi/ppapi.gyp:ppapi_proxy', + '../ppapi/ppapi_internal.gyp:ppapi_proxy', '../printing/printing.gyp:printing', '../skia/skia.gyp:skia', '../third_party/cld/cld.gyp:cld', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 05efaf9..c64d9c0 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -597,7 +597,7 @@ # run time dependencies 'chrome_mesa', 'default_plugin/default_plugin.gyp:default_plugin', - '../ppapi/ppapi.gyp:ppapi_tests', + '../ppapi/ppapi_internal.gyp:ppapi_tests', '../third_party/WebKit/Source/WebKit/chromium/WebKit.gyp:copy_TestNetscapePlugIn', ], 'include_dirs': [ diff --git a/chrome/nacl/nacl_launcher_thread.cc b/chrome/nacl/nacl_launcher_thread.cc index 6ea9a6c..ad1c5e4 100644 --- a/chrome/nacl/nacl_launcher_thread.cc +++ b/chrome/nacl/nacl_launcher_thread.cc @@ -12,7 +12,7 @@ #include "native_client/src/shared/imc/nacl_imc.h" #if defined(OS_LINUX) -#include "content/renderer/renderer_sandbox_support_linux.h" +#include "content/common/child_process_sandbox_support_linux.h" #endif #if defined(OS_WIN) @@ -97,7 +97,7 @@ void NaClLauncherThread::OnStartSelLdr( bool have_irt_file) { #if defined(OS_LINUX) nacl::SetCreateMemoryObjectFunc( - renderer_sandbox_support::MakeSharedMemorySegmentViaIPC); + child_process_sandbox_support::MakeSharedMemorySegmentViaIPC); #elif defined(OS_MACOSX) nacl::SetCreateMemoryObjectFunc(CreateMemoryObject); CHECK(handles.size() >= 1); diff --git a/content/renderer/renderer_sandbox_support_linux.cc b/content/common/child_process_sandbox_support_linux.cc index 11d27a6..92eea45 100644 --- a/content/renderer/renderer_sandbox_support_linux.cc +++ b/content/common/child_process_sandbox_support_linux.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/renderer/renderer_sandbox_support_linux.h" +#include "content/common/child_process_sandbox_support_linux.h" #include <sys/stat.h> @@ -13,14 +13,13 @@ #include "content/common/chrome_descriptors.h" #include "content/common/sandbox_methods_linux.h" #include "content/common/unix_domain_socket_posix.h" - #include "third_party/WebKit/Source/WebKit/chromium/public/linux/WebFontRenderStyle.h" static int GetSandboxFD() { return kSandboxIPCChannel + base::GlobalDescriptors::kBaseDescriptor; } -namespace renderer_sandbox_support { +namespace child_process_sandbox_support { std::string getFontFamilyForCharacters(const uint16_t* utf16, size_t num_utf16, @@ -186,4 +185,4 @@ bool GetFontTable(int fd, uint32_t table, uint8_t* output, return true; } -} // namespace render_sandbox_support +} // namespace child_process_sandbox_support diff --git a/content/renderer/renderer_sandbox_support_linux.h b/content/common/child_process_sandbox_support_linux.h index bc482bd..4e7b4fb 100644 --- a/content/renderer/renderer_sandbox_support_linux.h +++ b/content/common/child_process_sandbox_support_linux.h @@ -1,9 +1,9 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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 CONTENT_RENDERER_RENDERER_SANDBOX_SUPPORT_LINUX_H_ -#define CONTENT_RENDERER_RENDERER_SANDBOX_SUPPORT_LINUX_H_ +#ifndef CONTENT_COMMON_CHILD_PROCESS_SANDBOX_SUPPORT_LINUX_H_ +#define CONTENT_COMMON_CHILD_PROCESS_SANDBOX_SUPPORT_LINUX_H_ #pragma once #include <stdint.h> @@ -14,7 +14,7 @@ namespace WebKit { struct WebFontRenderStyle; } -namespace renderer_sandbox_support { +namespace child_process_sandbox_support { // Return a font family which provides glyphs for the Unicode code points // specified by |utf16| @@ -54,6 +54,6 @@ int MatchFontWithFallback(const std::string& face, bool bold, bool GetFontTable(int fd, uint32_t table, uint8_t* output, size_t* output_length); -}; // namespace render_sandbox_support +}; // namespace child_process_sandbox_support -#endif // CONTENT_RENDERER_RENDERER_SANDBOX_SUPPORT_LINUX_H_ +#endif // CONTENT_COMMON_CHILD_PROCESS_SANDBOX_SUPPORT_LINUX_H_ diff --git a/content/common/pepper_plugin_registry.cc b/content/common/pepper_plugin_registry.cc index c8b1c78..0d2a93c 100644 --- a/content/common/pepper_plugin_registry.cc +++ b/content/common/pepper_plugin_registry.cc @@ -232,5 +232,19 @@ base::WaitableEvent* PepperPluginRegistry::GetShutdownEvent() { std::set<PP_Instance>* PepperPluginRegistry::GetGloballySeenInstanceIDSet() { // This function is not needed on the host side of the proxy. + NOTREACHED(); return NULL; } + +pp::shared_impl::WebKitForwarding* PepperPluginRegistry::GetWebKitForwarding() { + // This function is not needed on the host side of the proxy. + NOTREACHED(); + return NULL; +} + +void PepperPluginRegistry::PostToWebKitThread( + const tracked_objects::Location& from_here, + const base::Closure& task) { + // This function is not needed on the host side of the proxy. + NOTREACHED(); +} diff --git a/content/common/pepper_plugin_registry.h b/content/common/pepper_plugin_registry.h index 7dd9038..ba4ea8a 100644 --- a/content/common/pepper_plugin_registry.h +++ b/content/common/pepper_plugin_registry.h @@ -100,6 +100,9 @@ class PepperPluginRegistry virtual base::MessageLoopProxy* GetIPCMessageLoop(); virtual base::WaitableEvent* GetShutdownEvent(); virtual std::set<PP_Instance>* GetGloballySeenInstanceIDSet(); + virtual pp::shared_impl::WebKitForwarding* GetWebKitForwarding(); + virtual void PostToWebKitThread(const tracked_objects::Location& from_here, + const base::Closure& task); // All known pepper plugins. std::vector<PepperPluginInfo> plugin_list_; diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 13d01c1..613b4a7 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -10,7 +10,7 @@ 'dependencies': [ 'content_common', '../app/app.gyp:app_resources', - '../ppapi/ppapi.gyp:ppapi_proxy', + '../ppapi/ppapi_internal.gyp:ppapi_proxy', '../skia/skia.gyp:skia', '../third_party/flac/flac.gyp:libflac', '../third_party/speex/speex.gyp:libspeex', diff --git a/content/content_common.gypi b/content/content_common.gypi index 2e61611..252cf74 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -43,6 +43,8 @@ 'common/child_process_info.cc', 'common/child_process_info.h', 'common/child_process_messages.h', + 'common/child_process_sandbox_support_linux.cc', + 'common/child_process_sandbox_support_linux.h', 'common/child_thread.cc', 'common/child_thread.h', 'common/child_trace_message_filter.cc', diff --git a/content/content_ppapi_plugin.gypi b/content/content_ppapi_plugin.gypi index e62050b..6dc13d3 100644 --- a/content/content_ppapi_plugin.gypi +++ b/content/content_ppapi_plugin.gypi @@ -9,7 +9,7 @@ 'type': '<(library)', 'dependencies': [ '../base/base.gyp:base', - '../ppapi/ppapi.gyp:ppapi_proxy', + '../ppapi/ppapi_internal.gyp:ppapi_proxy', ], 'sources': [ 'ppapi_plugin/broker_process_dispatcher.cc', @@ -20,6 +20,10 @@ 'ppapi_plugin/ppapi_plugin_main.cc', 'ppapi_plugin/ppapi_thread.cc', 'ppapi_plugin/ppapi_thread.h', + 'ppapi_plugin/ppapi_webkit_thread.cc', + 'ppapi_plugin/ppapi_webkit_thread.h', + 'ppapi_plugin/ppapi_webkitclient_impl.cc', + 'ppapi_plugin/ppapi_webkitclient_impl.h', ], 'include_dirs': [ '..', diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 21e6ac1..8271e75 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -11,7 +11,7 @@ 'dependencies': [ 'content_common', '../jingle/jingle.gyp:jingle_glue', - '../ppapi/ppapi.gyp:ppapi_proxy', + '../ppapi/ppapi_internal.gyp:ppapi_proxy', '../skia/skia.gyp:skia', '../third_party/ffmpeg/ffmpeg.gyp:ffmpeg', '../third_party/icu/icu.gyp:icuuc', @@ -102,8 +102,6 @@ 'renderer/renderer_main_platform_delegate_linux.cc', 'renderer/renderer_main_platform_delegate_mac.mm', 'renderer/renderer_main_platform_delegate_win.cc', - 'renderer/renderer_sandbox_support_linux.cc', - 'renderer/renderer_sandbox_support_linux.h', 'renderer/renderer_webapplicationcachehost_impl.cc', 'renderer/renderer_webapplicationcachehost_impl.h', 'renderer/renderer_webaudiodevice_impl.cc', diff --git a/content/ppapi_plugin/ppapi_thread.cc b/content/ppapi_plugin/ppapi_thread.cc index 91c3f85..73c0d5f 100644 --- a/content/ppapi_plugin/ppapi_thread.cc +++ b/content/ppapi_plugin/ppapi_thread.cc @@ -12,11 +12,13 @@ #include "content/common/child_process.h" #include "content/ppapi_plugin/broker_process_dispatcher.h" #include "content/ppapi_plugin/plugin_process_dispatcher.h" +#include "content/ppapi_plugin/ppapi_webkit_thread.h" #include "ipc/ipc_channel_handle.h" #include "ipc/ipc_sync_channel.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/ppp.h" #include "ppapi/proxy/ppapi_messages.h" +#include "webkit/plugins/ppapi/webkit_forwarding_impl.h" #if defined(OS_WIN) #include "sandbox/src/sandbox.h" @@ -81,6 +83,19 @@ std::set<PP_Instance>* PpapiThread::GetGloballySeenInstanceIDSet() { return &globally_seen_instance_ids_; } +pp::shared_impl::WebKitForwarding* PpapiThread::GetWebKitForwarding() { + if (!webkit_forwarding_.get()) + webkit_forwarding_.reset(new webkit::ppapi::WebKitForwardingImpl); + return webkit_forwarding_.get(); +} + +void PpapiThread::PostToWebKitThread(const tracked_objects::Location& from_here, + const base::Closure& task) { + if (!webkit_thread_.get()) + webkit_thread_.reset(new PpapiWebKitThread); + webkit_thread_->PostTask(from_here, task); +} + void PpapiThread::OnMsgLoadPlugin(const FilePath& path) { base::ScopedNativeLibrary library(base::LoadNativeLibrary(path, NULL)); diff --git a/content/ppapi_plugin/ppapi_thread.h b/content/ppapi_plugin/ppapi_thread.h index 50bda11..5b7e3c4 100644 --- a/content/ppapi_plugin/ppapi_thread.h +++ b/content/ppapi_plugin/ppapi_thread.h @@ -17,6 +17,7 @@ #include "ppapi/c/trusted/ppp_broker.h" class FilePath; +class PpapiWebKitThread; namespace IPC { struct ChannelHandle; @@ -36,6 +37,9 @@ class PpapiThread : public ChildThread, virtual base::MessageLoopProxy* GetIPCMessageLoop(); virtual base::WaitableEvent* GetShutdownEvent(); virtual std::set<PP_Instance>* GetGloballySeenInstanceIDSet(); + virtual pp::shared_impl::WebKitForwarding* GetWebKitForwarding(); + virtual void PostToWebKitThread(const tracked_objects::Location& from_here, + const base::Closure& task); // Message handlers. void OnMsgLoadPlugin(const FilePath& path); @@ -70,6 +74,11 @@ class PpapiThread : public ChildThread, // See Dispatcher::Delegate::GetGloballySeenInstanceIDSet. std::set<PP_Instance> globally_seen_instance_ids_; + // Lazily created by GetWebKitForwarding. + scoped_ptr<pp::shared_impl::WebKitForwarding> webkit_forwarding_; + + scoped_ptr<PpapiWebKitThread> webkit_thread_; + DISALLOW_IMPLICIT_CONSTRUCTORS(PpapiThread); }; diff --git a/content/ppapi_plugin/ppapi_webkit_thread.cc b/content/ppapi_plugin/ppapi_webkit_thread.cc new file mode 100644 index 0000000..1320138 --- /dev/null +++ b/content/ppapi_plugin/ppapi_webkit_thread.cc @@ -0,0 +1,44 @@ +// 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 "content/ppapi_plugin/ppapi_webkit_thread.h" + +#include "base/logging.h" +#include "content/ppapi_plugin/ppapi_webkitclient_impl.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" + +PpapiWebKitThread::PpapiWebKitThread() { + DCHECK(!webkit_thread_.get()); + + webkit_thread_.reset(new InternalWebKitThread); + bool started = webkit_thread_->Start(); + DCHECK(started); +} + +PpapiWebKitThread::~PpapiWebKitThread() { +} + +void PpapiWebKitThread::PostTask(const tracked_objects::Location& from_here, + const base::Closure& task) { + webkit_thread_->message_loop()->PostTask(from_here, task); +} + +PpapiWebKitThread::InternalWebKitThread::InternalWebKitThread() + : base::Thread("PPAPIWebKit") { +} + +PpapiWebKitThread::InternalWebKitThread::~InternalWebKitThread() { + Stop(); +} + +void PpapiWebKitThread::InternalWebKitThread::Init() { + DCHECK(!webkit_client_.get()); + webkit_client_.reset(new PpapiWebKitClientImpl); + WebKit::initialize(webkit_client_.get()); +} + +void PpapiWebKitThread::InternalWebKitThread::CleanUp() { + DCHECK(webkit_client_.get()); + WebKit::shutdown(); +} diff --git a/content/ppapi_plugin/ppapi_webkit_thread.h b/content/ppapi_plugin/ppapi_webkit_thread.h new file mode 100644 index 0000000..a6f338e --- /dev/null +++ b/content/ppapi_plugin/ppapi_webkit_thread.h @@ -0,0 +1,50 @@ +// 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 CONTENT_PPAPI_PLUGIN_PPAPI_WEBKIT_THREAD_H_ +#define CONTENT_PPAPI_PLUGIN_PPAPI_WEBKIT_THREAD_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "base/threading/thread.h" + +class PpapiWebKitClientImpl; + +// This creates a WebKit main thread on instantiation on construction and kills +// it on deletion. See also content/browser/in_process_webkit for the +// corresponding concept in the browser process. +class PpapiWebKitThread { + public: + PpapiWebKitThread(); + ~PpapiWebKitThread(); + + // Posts the given task to the thread, see MessageLoop::PostTask. + void PostTask( + const tracked_objects::Location& from_here, + const base::Closure& task); + + private: + // Must be private so that we can carefully control its lifetime. + class InternalWebKitThread : public base::Thread { + public: + InternalWebKitThread(); + virtual ~InternalWebKitThread(); + // Does the actual initialization and shutdown of WebKit. Called at the + // beginning and end of the thread's lifetime. + virtual void Init(); + virtual void CleanUp(); + + private: + // The WebKitClient implementation. Only access on WebKit thread. + scoped_ptr<PpapiWebKitClientImpl> webkit_client_; + }; + + // Pointer to the actual WebKitThread. + scoped_ptr<InternalWebKitThread> webkit_thread_; + + DISALLOW_COPY_AND_ASSIGN(PpapiWebKitThread); +}; + +#endif // CONTENT_PPAPI_PLUGIN_PPAPI_WEBKIT_THREAD_H_ diff --git a/content/ppapi_plugin/ppapi_webkitclient_impl.cc b/content/ppapi_plugin/ppapi_webkitclient_impl.cc new file mode 100644 index 0000000..1abbe94 --- /dev/null +++ b/content/ppapi_plugin/ppapi_webkitclient_impl.cc @@ -0,0 +1,238 @@ +// 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 "content/ppapi_plugin/ppapi_webkitclient_impl.h" + +#include <map> + +#include "base/synchronization/lock.h" +#include "base/logging.h" +#include "base/string16.h" +#include "build/build_config.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebSerializedScriptValue.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" + +#if defined(OS_WIN) +#include "third_party/WebKit/Source/WebKit/chromium/public/win/WebSandboxSupport.h" +#elif defined(OS_MACOSX) +#include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebSandboxSupport.h" +#elif defined(OS_LINUX) +#include "content/common/child_process_sandbox_support_linux.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/linux/WebSandboxSupport.h" +#endif + +using WebKit::WebSandboxSupport; +using WebKit::WebString; +using WebKit::WebUChar; + +class PpapiWebKitClientImpl::SandboxSupport : public WebSandboxSupport { + public: +#if defined(OS_WIN) + virtual bool ensureFontLoaded(HFONT); +#elif defined(OS_MACOSX) + virtual bool loadFont(NSFont* srcFont, ATSFontContainerRef* out); +#elif defined(OS_LINUX) + virtual WebString getFontFamilyForCharacters( + const WebUChar* characters, + size_t numCharacters, + const char* preferred_locale); + virtual void getRenderStyleForStrike( + const char* family, int sizeAndStyle, WebKit::WebFontRenderStyle* out); + + private: + // WebKit likes to ask us for the correct font family to use for a set of + // unicode code points. It needs this information frequently so we cache it + // here. The key in this map is an array of 16-bit UTF16 values from WebKit. + // The value is a string containing the correct font family. + base::Lock unicode_font_families_mutex_; + std::map<string16, std::string> unicode_font_families_; +#endif +}; + +#if defined(OS_WIN) + +bool PpapiWebKitClientImpl::SandboxSupport::ensureFontLoaded(HFONT font) { + // TODO(brettw) this should do the something similar to what + // RendererWebKitClientImpl does and request that the browser load the font. + NOTIMPLEMENTED(); + return false; +} + +#elif defined(OS_MACOSX) + +bool PpapiWebKitClientImpl::SandboxSupport::loadFont(NSFont* srcFont, + ATSFontContainerRef* out) { + // TODO(brettw) this should do the something similar to what + // RendererWebKitClientImpl does and request that the browser load the font. + NOTIMPLEMENTED(); + return false; +} + +#elif defined(OS_LINUX) + +WebString PpapiWebKitClientImpl::SandboxSupport::getFontFamilyForCharacters( + const WebUChar* characters, + size_t num_characters, + const char* preferred_locale) { + base::AutoLock lock(unicode_font_families_mutex_); + const string16 key(characters, num_characters); + const std::map<string16, std::string>::const_iterator iter = + unicode_font_families_.find(key); + if (iter != unicode_font_families_.end()) + return WebString::fromUTF8(iter->second); + + const std::string family_name = + child_process_sandbox_support::getFontFamilyForCharacters( + characters, + num_characters, + preferred_locale); + unicode_font_families_.insert(make_pair(key, family_name)); + return WebString::fromUTF8(family_name); +} + +void PpapiWebKitClientImpl::SandboxSupport::getRenderStyleForStrike( + const char* family, int sizeAndStyle, WebKit::WebFontRenderStyle* out) { + child_process_sandbox_support::getRenderStyleForStrike(family, sizeAndStyle, + out); +} + +#endif + +PpapiWebKitClientImpl::PpapiWebKitClientImpl() { +} + +PpapiWebKitClientImpl::~PpapiWebKitClientImpl() { +} + +WebKit::WebClipboard* PpapiWebKitClientImpl::clipboard() { + NOTREACHED(); + return NULL; +} + +WebKit::WebMimeRegistry* PpapiWebKitClientImpl::mimeRegistry() { + NOTREACHED(); + return NULL; +} + +WebKit::WebFileUtilities* PpapiWebKitClientImpl::fileUtilities() { + NOTREACHED(); + return NULL; +} + +WebKit::WebSandboxSupport* PpapiWebKitClientImpl::sandboxSupport() { + return sandbox_support_.get(); +} + +bool PpapiWebKitClientImpl::sandboxEnabled() { + return true; // Assume PPAPI is always sandboxed. +} + +unsigned long long PpapiWebKitClientImpl::visitedLinkHash( + const char* canonical_url, + size_t length) { + NOTREACHED(); + return 0; +} + +bool PpapiWebKitClientImpl::isLinkVisited(unsigned long long link_hash) { + NOTREACHED(); + return false; +} + +WebKit::WebMessagePortChannel* +PpapiWebKitClientImpl::createMessagePortChannel() { + NOTREACHED(); + return NULL; +} + +void PpapiWebKitClientImpl::setCookies( + const WebKit::WebURL& url, + const WebKit::WebURL& first_party_for_cookies, + const WebKit::WebString& value) { + NOTREACHED(); +} + +WebKit::WebString PpapiWebKitClientImpl::cookies( + const WebKit::WebURL& url, + const WebKit::WebURL& first_party_for_cookies) { + NOTREACHED(); + return WebKit::WebString(); +} + +void PpapiWebKitClientImpl::prefetchHostName(const WebKit::WebString&) { + NOTREACHED(); +} + +WebKit::WebString PpapiWebKitClientImpl::defaultLocale() { + NOTREACHED(); + return WebKit::WebString(); +} + +WebKit::WebThemeEngine* PpapiWebKitClientImpl::themeEngine() { + NOTREACHED(); + return NULL; +} + +WebKit::WebURLLoader* PpapiWebKitClientImpl::createURLLoader() { + NOTREACHED(); + return NULL; +} + +WebKit::WebSocketStreamHandle* + PpapiWebKitClientImpl::createSocketStreamHandle() { + NOTREACHED(); + return NULL; +} + +void PpapiWebKitClientImpl::getPluginList(bool refresh, + WebKit::WebPluginListBuilder* builder) { + NOTREACHED(); +} + +WebKit::WebData PpapiWebKitClientImpl::loadResource(const char* name) { + NOTREACHED(); + return WebKit::WebData(); +} + +WebKit::WebStorageNamespace* +PpapiWebKitClientImpl::createLocalStorageNamespace( + const WebKit::WebString& path, unsigned quota) { + NOTREACHED(); + return 0; +} + +void PpapiWebKitClientImpl::dispatchStorageEvent( + const WebKit::WebString& key, const WebKit::WebString& old_value, + const WebKit::WebString& new_value, const WebKit::WebString& origin, + const WebKit::WebURL& url, bool is_local_storage) { + NOTREACHED(); +} + +WebKit::WebSharedWorkerRepository* +PpapiWebKitClientImpl::sharedWorkerRepository() { + NOTREACHED(); + return NULL; +} + +int PpapiWebKitClientImpl::databaseDeleteFile( + const WebKit::WebString& vfs_file_name, bool sync_dir) { + NOTREACHED(); + return 0; +} + +void PpapiWebKitClientImpl::createIDBKeysFromSerializedValuesAndKeyPath( + const WebKit::WebVector<WebKit::WebSerializedScriptValue>& values, + const WebKit::WebString& keyPath, + WebKit::WebVector<WebKit::WebIDBKey>& keys) { + NOTREACHED(); +} + +WebKit::WebSerializedScriptValue +PpapiWebKitClientImpl::injectIDBKeyIntoSerializedValue( + const WebKit::WebIDBKey& key, + const WebKit::WebSerializedScriptValue& value, + const WebKit::WebString& keyPath) { + NOTREACHED(); + return WebKit::WebSerializedScriptValue(); +} diff --git a/content/ppapi_plugin/ppapi_webkitclient_impl.h b/content/ppapi_plugin/ppapi_webkitclient_impl.h new file mode 100644 index 0000000..5c3b90e --- /dev/null +++ b/content/ppapi_plugin/ppapi_webkitclient_impl.h @@ -0,0 +1,66 @@ +// 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 CONTENT_PPAPI_PLUGIN_PPAPI_WEBKITCLIENT_IMPL_H_ +#define CONTENT_PPAPI_PLUGIN_PPAPI_WEBKITCLIENT_IMPL_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/scoped_ptr.h" +#include "webkit/glue/webkitclient_impl.h" + +class PpapiWebKitClientImpl : public webkit_glue::WebKitClientImpl { + public: + PpapiWebKitClientImpl(); + virtual ~PpapiWebKitClientImpl(); + + // WebKitClient methods: + virtual WebKit::WebClipboard* clipboard(); + virtual WebKit::WebMimeRegistry* mimeRegistry(); + virtual WebKit::WebFileUtilities* fileUtilities(); + virtual WebKit::WebSandboxSupport* sandboxSupport(); + virtual bool sandboxEnabled(); + virtual unsigned long long visitedLinkHash(const char* canonicalURL, + size_t length); + virtual bool isLinkVisited(unsigned long long linkHash); + virtual WebKit::WebMessagePortChannel* createMessagePortChannel(); + virtual void setCookies(const WebKit::WebURL& url, + const WebKit::WebURL& first_party_for_cookies, + const WebKit::WebString& value); + virtual WebKit::WebString cookies( + const WebKit::WebURL& url, + const WebKit::WebURL& first_party_for_cookies); + virtual void prefetchHostName(const WebKit::WebString&); + virtual WebKit::WebString defaultLocale(); + virtual WebKit::WebThemeEngine* themeEngine(); + virtual WebKit::WebURLLoader* createURLLoader(); + virtual WebKit::WebSocketStreamHandle* createSocketStreamHandle(); + virtual void getPluginList(bool refresh, WebKit::WebPluginListBuilder*); + virtual WebKit::WebData loadResource(const char* name); + virtual WebKit::WebStorageNamespace* createLocalStorageNamespace( + const WebKit::WebString& path, unsigned quota); + virtual void dispatchStorageEvent(const WebKit::WebString& key, + const WebKit::WebString& oldValue, const WebKit::WebString& newValue, + const WebKit::WebString& origin, const WebKit::WebURL& url, + bool isLocalStorage); + virtual WebKit::WebSharedWorkerRepository* sharedWorkerRepository(); + virtual int databaseDeleteFile(const WebKit::WebString& vfs_file_name, + bool sync_dir); + virtual void createIDBKeysFromSerializedValuesAndKeyPath( + const WebKit::WebVector<WebKit::WebSerializedScriptValue>& values, + const WebKit::WebString& keyPath, + WebKit::WebVector<WebKit::WebIDBKey>& keys); + virtual WebKit::WebSerializedScriptValue injectIDBKeyIntoSerializedValue( + const WebKit::WebIDBKey& key, + const WebKit::WebSerializedScriptValue& value, + const WebKit::WebString& keyPath); + + private: + class SandboxSupport; + scoped_ptr<SandboxSupport> sandbox_support_; + + DISALLOW_COPY_AND_ASSIGN(PpapiWebKitClientImpl); +}; + +#endif // CONTENT_PPAPI_PLUGIN_PPAPI_WEBKITCLIENT_IMPL_H_ diff --git a/content/renderer/render_process_impl.cc b/content/renderer/render_process_impl.cc index c03878e..1ded505 100644 --- a/content/renderer/render_process_impl.cc +++ b/content/renderer/render_process_impl.cc @@ -37,10 +37,6 @@ #include "base/mac/mac_util.h" #endif -#if defined(OS_LINUX) -#include "content/renderer/renderer_sandbox_support_linux.h" -#endif - RenderProcessImpl::RenderProcessImpl() : ALLOW_THIS_IN_INITIALIZER_LIST(shared_mem_cache_cleaner_( base::TimeDelta::FromSeconds(5), diff --git a/content/renderer/renderer_glue.cc b/content/renderer/renderer_glue.cc index 5ad03fd..8c78846 100644 --- a/content/renderer/renderer_glue.cc +++ b/content/renderer/renderer_glue.cc @@ -35,7 +35,7 @@ #include "webkit/glue/websocketstreamhandle_bridge.h" #if defined(OS_LINUX) -#include "content/renderer/renderer_sandbox_support_linux.h" +#include "content/common/child_process_sandbox_support_linux.h" #endif // This definition of WriteBitmapFromPixels uses shared memory to communicate @@ -262,13 +262,13 @@ void EnableSpdy(bool enable) { #if defined(OS_LINUX) int MatchFontWithFallback(const std::string& face, bool bold, bool italic, int charset) { - return renderer_sandbox_support::MatchFontWithFallback( + return child_process_sandbox_support::MatchFontWithFallback( face, bold, italic, charset); } bool GetFontTable(int fd, uint32_t table, uint8_t* output, size_t* output_length) { - return renderer_sandbox_support::GetFontTable( + return child_process_sandbox_support::GetFontTable( fd, table, output, output_length); } #endif diff --git a/content/renderer/renderer_webkitclient_impl.cc b/content/renderer/renderer_webkitclient_impl.cc index 99746c9..c68cc58 100644 --- a/content/renderer/renderer_webkitclient_impl.cc +++ b/content/renderer/renderer_webkitclient_impl.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -61,7 +61,7 @@ #include <map> #include "base/synchronization/lock.h" -#include "content/renderer/renderer_sandbox_support_linux.h" +#include "content/common/child_process_sandbox_support_linux.h" #include "third_party/WebKit/Source/WebKit/chromium/public/linux/WebSandboxSupport.h" #endif @@ -128,7 +128,7 @@ class RendererWebKitClientImpl::SandboxSupport // here. The key in this map is an array of 16-bit UTF16 values from WebKit. // The value is a string containing the correct font family. base::Lock unicode_font_families_mutex_; - std::map<std::string, std::string> unicode_font_families_; + std::map<string16, std::string> unicode_font_families_; #endif }; @@ -440,24 +440,25 @@ WebString RendererWebKitClientImpl::SandboxSupport::getFontFamilyForCharacters( size_t num_characters, const char* preferred_locale) { base::AutoLock lock(unicode_font_families_mutex_); - const std::string key(reinterpret_cast<const char*>(characters), - num_characters * sizeof(characters[0])); - const std::map<std::string, std::string>::const_iterator iter = + const string16 key(characters, num_characters); + const std::map<string16, std::string>::const_iterator iter = unicode_font_families_.find(key); if (iter != unicode_font_families_.end()) return WebString::fromUTF8(iter->second); const std::string family_name = - renderer_sandbox_support::getFontFamilyForCharacters(characters, - num_characters, - preferred_locale); + child_process_sandbox_support::getFontFamilyForCharacters( + characters, + num_characters, + preferred_locale); unicode_font_families_.insert(make_pair(key, family_name)); return WebString::fromUTF8(family_name); } void RendererWebKitClientImpl::SandboxSupport::getRenderStyleForStrike( const char* family, int sizeAndStyle, WebKit::WebFontRenderStyle* out) { - renderer_sandbox_support::getRenderStyleForStrike(family, sizeAndStyle, out); + child_process_sandbox_support::getRenderStyleForStrike(family, sizeAndStyle, + out); } #elif defined(OS_MACOSX) 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(); diff --git a/webkit/glue/gl_bindings_skia_cmd_buffer.cc b/webkit/glue/gl_bindings_skia_cmd_buffer.cc index c7f8d4f..39653e2 100644 --- a/webkit/glue/gl_bindings_skia_cmd_buffer.cc +++ b/webkit/glue/gl_bindings_skia_cmd_buffer.cc @@ -5,7 +5,9 @@ #include "webkit/glue/gl_bindings_skia_cmd_buffer.h" +#ifndef GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES +#endif #include "gpu/GLES2/gl2.h" #include "gpu/GLES2/gl2ext.h" diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi index 23b9634..53a6912 100644 --- a/webkit/glue/webkit_glue.gypi +++ b/webkit/glue/webkit_glue.gypi @@ -109,13 +109,13 @@ '<(DEPTH)/base/base.gyp:base_i18n', '<(DEPTH)/gpu/gpu.gyp:gles2_implementation', '<(DEPTH)/net/net.gyp:net', - '<(DEPTH)/ppapi/ppapi.gyp:ppapi_shared_impl', + '<(DEPTH)/ppapi/ppapi.gyp:ppapi_c', + '<(DEPTH)/ppapi/ppapi_internal.gyp:ppapi_shared_impl', '<(DEPTH)/printing/printing.gyp:printing', '<(DEPTH)/skia/skia.gyp:skia', '<(DEPTH)/third_party/icu/icu.gyp:icui18n', '<(DEPTH)/third_party/icu/icu.gyp:icuuc', '<(DEPTH)/third_party/npapi/npapi.gyp:npapi', - '<(DEPTH)/ppapi/ppapi.gyp:ppapi_c', 'webkit_resources', 'webkit_strings', 'webkit_user_agent', @@ -314,6 +314,8 @@ '../plugins/ppapi/string.h', '../plugins/ppapi/var.cc', '../plugins/ppapi/var.h', + '../plugins/ppapi/webkit_forwarding_impl.cc', + '../plugins/ppapi/webkit_forwarding_impl.h', '../plugins/sad_plugin.cc', '../plugins/sad_plugin.h', 'media/audio_decoder.cc', diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc index f22ca92..6d4543f 100644 --- a/webkit/plugins/ppapi/plugin_module.cc +++ b/webkit/plugins/ppapi/plugin_module.cc @@ -105,6 +105,7 @@ #include "webkit/plugins/ppapi/ppb_widget_impl.h" #include "webkit/plugins/ppapi/resource_tracker.h" #include "webkit/plugins/ppapi/var.h" +#include "webkit/plugins/ppapi/webkit_forwarding_impl.h" #ifdef ENABLE_GPU #include "webkit/plugins/ppapi/ppb_context_3d_impl.h" @@ -562,6 +563,12 @@ PluginDelegate::PpapiBroker* PluginModule::GetBroker(){ return broker_; } +pp::shared_impl::WebKitForwarding* PluginModule::GetWebKitForwarding() { + if (!webkit_forwarding_.get()) + webkit_forwarding_.reset(new WebKitForwardingImpl); + return webkit_forwarding_.get(); +} + bool PluginModule::InitializeModule() { DCHECK(!out_of_process_proxy_.get()) << "Don't call for proxied modules."; int retval = entry_points_.initialize_module(pp_module(), &GetInterface); diff --git a/webkit/plugins/ppapi/plugin_module.h b/webkit/plugins/ppapi/plugin_module.h index 1ade5a6..d1fa058 100644 --- a/webkit/plugins/ppapi/plugin_module.h +++ b/webkit/plugins/ppapi/plugin_module.h @@ -32,10 +32,16 @@ class WaitableEvent; } namespace pp { + namespace proxy { class HostDispatcher; -} // proxy -} // pp +} // namespace proxy + +namespace shared_impl { +class WebKitForwarding; +} // namespace shared_impl + +} // namespace pp namespace IPC { struct ChannelHandle; @@ -149,6 +155,9 @@ class PluginModule : public base::RefCounted<PluginModule>, void SetBroker(PluginDelegate::PpapiBroker* broker); PluginDelegate::PpapiBroker* GetBroker(); + // Retrieves the forwarding interface used for talking to WebKit. + pp::shared_impl::WebKitForwarding* GetWebKitForwarding(); + private: // Calls the InitializeModule entrypoint. The entrypoint must have been // set and the plugin must not be out of process (we don't maintain @@ -197,6 +206,9 @@ class PluginModule : public base::RefCounted<PluginModule>, PP_Bool (*reserve_instance_id_)(PP_Module, PP_Instance); + // Lazily created by GetWebKitForwarding. + scoped_ptr<pp::shared_impl::WebKitForwarding> webkit_forwarding_; + DISALLOW_COPY_AND_ASSIGN(PluginModule); }; diff --git a/webkit/plugins/ppapi/ppb_font_impl.cc b/webkit/plugins/ppapi/ppb_font_impl.cc index b0a99ada..02fd5a9 100644 --- a/webkit/plugins/ppapi/ppb_font_impl.cc +++ b/webkit/plugins/ppapi/ppb_font_impl.cc @@ -1,196 +1,50 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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 "webkit/plugins/ppapi/ppb_font_impl.h" -#include "base/logging.h" -#include "base/utf_string_conversions.h" #include "ppapi/c/dev/ppb_font_dev.h" -#include "ppapi/c/pp_rect.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebFont.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebFontDescription.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebFloatPoint.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebFloatRect.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebTextRun.h" +#include "ppapi/thunk/thunk.h" #include "webkit/plugins/ppapi/common.h" +#include "webkit/plugins/ppapi/plugin_module.h" #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" #include "webkit/plugins/ppapi/ppb_image_data_impl.h" #include "webkit/plugins/ppapi/string.h" #include "webkit/plugins/ppapi/var.h" -#include "webkit/glue/webkit_glue.h" -using WebKit::WebFloatPoint; -using WebKit::WebFloatRect; -using WebKit::WebFont; -using WebKit::WebFontDescription; -using WebKit::WebRect; -using WebKit::WebTextRun; +using pp::shared_impl::WebKitForwarding; namespace webkit { namespace ppapi { namespace { -bool IsPPFontDescriptionValid(const PP_FontDescription_Dev& desc) { - // Check validity of UTF-8. - 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; -} - -// The PP_* version lacks "None", so is just one value shifted from the -// WebFontDescription version. These values are checked in -// PPFontDescToWebFontDesc to make sure the conversion is correct. This is a -// macro so it can also be used in the COMPILE_ASSERTS. -#define PP_FONTFAMILY_TO_WEB_FONTFAMILY(f) \ - static_cast<WebFontDescription::GenericFamily>(f + 1) - -// Assumes the given PP_FontDescription has been validated. -WebFontDescription PPFontDescToWebFontDesc(const PP_FontDescription_Dev& font) { - // Verify that the enums match so we can just static cast. - COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight100) == - static_cast<int>(PP_FONTWEIGHT_100), - FontWeight100); - COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight900) == - static_cast<int>(PP_FONTWEIGHT_900), - FontWeight900); - COMPILE_ASSERT(WebFontDescription::GenericFamilyStandard == - PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_DEFAULT), - StandardFamily); - COMPILE_ASSERT(WebFontDescription::GenericFamilySerif == - PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_SERIF), - SerifFamily); - COMPILE_ASSERT(WebFontDescription::GenericFamilySansSerif == - PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_SANSSERIF), - SansSerifFamily); - COMPILE_ASSERT(WebFontDescription::GenericFamilyMonospace == - PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_MONOSPACE), - MonospaceFamily); - - WebFontDescription result; - scoped_refptr<StringVar> face_name(StringVar::FromPPVar(font.face)); - if (face_name) - result.family = UTF8ToUTF16(face_name->value()); - result.genericFamily = PP_FONTFAMILY_TO_WEB_FONTFAMILY(font.family); - result.size = static_cast<float>(font.size); - result.italic = PPBoolToBool(font.italic); - result.smallCaps = PPBoolToBool(font.small_caps); - result.weight = static_cast<WebFontDescription::Weight>(font.weight); - result.letterSpacing = static_cast<short>(font.letter_spacing); - result.wordSpacing = static_cast<short>(font.word_spacing); - return result; -} - -// Converts the given PP_TextRun to a WebTextRun, returning true on success. +// Converts the given PP_TextRun to a TextRun, returning true on success. // False means the input was invalid. -bool PPTextRunToWebTextRun(const PP_TextRun_Dev* run, WebTextRun* output) { +bool PPTextRunToTextRun(const PP_TextRun_Dev* run, + WebKitForwarding::Font::TextRun* output) { scoped_refptr<StringVar> text_string(StringVar::FromPPVar(run->text)); if (!text_string) return false; - *output = WebTextRun(UTF8ToUTF16(text_string->value()), - PPBoolToBool(run->rtl), - PPBoolToBool(run->override_direction)); - return true; -} - -PP_Resource Create(PP_Instance instance_id, - const PP_FontDescription_Dev* description) { - PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); - if (!instance) - return 0; - - if (!IsPPFontDescriptionValid(*description)) - return 0; - - scoped_refptr<PPB_Font_Impl> font(new PPB_Font_Impl(instance, *description)); - return font->GetReference(); -} - -PP_Bool IsFont(PP_Resource resource) { - return BoolToPPBool(!!Resource::GetAs<PPB_Font_Impl>(resource).get()); -} - -PP_Bool Describe(PP_Resource font_id, - PP_FontDescription_Dev* description, - PP_FontMetrics_Dev* metrics) { - scoped_refptr<PPB_Font_Impl> font(Resource::GetAs<PPB_Font_Impl>(font_id)); - if (!font.get()) - return PP_FALSE; - return BoolToPPBool(font->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) { - scoped_refptr<PPB_Font_Impl> font(Resource::GetAs<PPB_Font_Impl>(font_id)); - if (!font.get()) - return PP_FALSE; - return BoolToPPBool(font->DrawTextAt(image_data, text, position, color, clip, - PPBoolToBool(image_data_is_opaque))); -} - -int32_t MeasureText(PP_Resource font_id, const PP_TextRun_Dev* text) { - scoped_refptr<PPB_Font_Impl> font(Resource::GetAs<PPB_Font_Impl>(font_id)); - if (!font.get()) - return -1; - return font->MeasureText(text); -} -uint32_t CharacterOffsetForPixel(PP_Resource font_id, - const PP_TextRun_Dev* text, - int32_t pixel_position) { - scoped_refptr<PPB_Font_Impl> font(Resource::GetAs<PPB_Font_Impl>(font_id)); - if (!font.get()) - return -1; - return font->CharacterOffsetForPixel(text, pixel_position); -} - -int32_t PixelOffsetForCharacter(PP_Resource font_id, - const PP_TextRun_Dev* text, - uint32_t char_offset) { - scoped_refptr<PPB_Font_Impl> font(Resource::GetAs<PPB_Font_Impl>(font_id)); - if (!font.get()) - return false; - return font->PixelOffsetForCharacter(text, char_offset); + output->text = text_string->value(); + output->rtl = PPBoolToBool(run->rtl); + output->override_direction = PPBoolToBool(run->override_direction); + return true; } -const PPB_Font_Dev ppb_font = { - &Create, - &IsFont, - &Describe, - &DrawTextAt, - &MeasureText, - &CharacterOffsetForPixel, - &PixelOffsetForCharacter -}; - } // namespace PPB_Font_Impl::PPB_Font_Impl(PluginInstance* instance, const PP_FontDescription_Dev& desc) : Resource(instance) { - WebFontDescription web_font_desc = PPFontDescToWebFontDesc(desc); - font_.reset(WebFont::create(web_font_desc)); + scoped_refptr<StringVar> face_name(StringVar::FromPPVar(desc.face)); + + WebKitForwarding::Font* result = NULL; + instance->module()->GetWebKitForwarding()->CreateFontForwarding( + NULL, desc, face_name ? face_name->value() : std::string(), &result); + font_forwarding_.reset(result); } PPB_Font_Impl::~PPB_Font_Impl() { @@ -198,103 +52,82 @@ PPB_Font_Impl::~PPB_Font_Impl() { // static const PPB_Font_Dev* PPB_Font_Impl::GetInterface() { - return &ppb_font; + return ::ppapi::thunk::GetPPB_Font_Thunk(); } -PPB_Font_Impl* PPB_Font_Impl::AsPPB_Font_Impl() { +::ppapi::thunk::PPB_Font_API* PPB_Font_Impl::AsFont_API() { return this; } -bool PPB_Font_Impl::Describe(PP_FontDescription_Dev* description, - PP_FontMetrics_Dev* metrics) { - if (description->face.type != PP_VARTYPE_UNDEFINED) - return false; - - WebFontDescription web_desc = font_->fontDescription(); - - // While converting the other way in PPFontDescToWebFontDesc we validated - // that the enums can be casted. - description->face = StringVar::StringToPPVar(instance()->module(), - UTF16ToUTF8(web_desc.family)); - description->family = static_cast<PP_FontFamily_Dev>(web_desc.genericFamily); - description->size = static_cast<uint32_t>(web_desc.size); - description->weight = static_cast<PP_FontWeight_Dev>(web_desc.weight); - description->italic = BoolToPPBool(web_desc.italic); - description->small_caps = BoolToPPBool(web_desc.smallCaps); +PPB_Font_Impl* PPB_Font_Impl::AsPPB_Font_Impl() { + return this; +} - metrics->height = font_->height(); - metrics->ascent = font_->ascent(); - metrics->descent = font_->descent(); - metrics->line_spacing = font_->lineSpacing(); - metrics->x_height = static_cast<int32_t>(font_->xHeight()); +PP_Bool PPB_Font_Impl::Describe(PP_FontDescription_Dev* description, + PP_FontMetrics_Dev* metrics) { + std::string face; + PP_Bool result = PP_FALSE; + font_forwarding_->Describe(NULL, description, &face, metrics, &result); + if (!result) + return PP_FALSE; - return true; + // Convert the string. + description->face = StringVar::StringToPPVar(instance()->module(), face); + return PP_TRUE; } -bool PPB_Font_Impl::DrawTextAt(PP_Resource image_data, - const PP_TextRun_Dev* text, - const PP_Point* position, - uint32_t color, - const PP_Rect* clip, - bool image_data_is_opaque) { - WebTextRun run; - if (!PPTextRunToWebTextRun(text, &run)) - return false; - +PP_Bool PPB_Font_Impl::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) { // Get and map the image data we're painting to. scoped_refptr<PPB_ImageData_Impl> image_resource( Resource::GetAs<PPB_ImageData_Impl>(image_data)); if (!image_resource.get()) - return false; + return PP_FALSE; ImageDataAutoMapper mapper(image_resource); if (!mapper.is_valid()) - return false; + return PP_FALSE; - // Convert position and clip. - WebFloatPoint web_position(static_cast<float>(position->x), - static_cast<float>(position->y)); - WebRect web_clip; - if (!clip) { - // Use entire canvas. - web_clip = WebRect(0, 0, image_resource->width(), image_resource->height()); - } else { - web_clip = WebRect(clip->point.x, clip->point.y, - clip->size.width, clip->size.height); - } + WebKitForwarding::Font::TextRun run; + if (!PPTextRunToTextRun(text, &run)) + return PP_FALSE; - font_->drawText(webkit_glue::ToWebCanvas(image_resource->mapped_canvas()), - run, web_position, color, web_clip, image_data_is_opaque); - return true; + font_forwarding_->DrawTextAt(NULL, WebKitForwarding::Font::DrawTextParams( + image_resource->mapped_canvas(), run, position, + color, clip, image_data_is_opaque)); + return PP_TRUE; } int32_t PPB_Font_Impl::MeasureText(const PP_TextRun_Dev* text) { - WebTextRun run; - if (!PPTextRunToWebTextRun(text, &run)) - return -1; - return font_->calculateWidth(run); + int32_t result = -1; + WebKitForwarding::Font::TextRun run; + if (PPTextRunToTextRun(text, &run)) + font_forwarding_->MeasureText(NULL, run, &result); + return result; } uint32_t PPB_Font_Impl::CharacterOffsetForPixel(const PP_TextRun_Dev* text, int32_t pixel_position) { - WebTextRun run; - if (!PPTextRunToWebTextRun(text, &run)) - return -1; - - return static_cast<uint32_t>(font_->offsetForPosition( - run, static_cast<float>(pixel_position))); + uint32_t result = -1; + WebKitForwarding::Font::TextRun run; + if (PPTextRunToTextRun(text, &run)) { + font_forwarding_->CharacterOffsetForPixel(NULL, run, pixel_position, + &result); + } + return result; } int32_t PPB_Font_Impl::PixelOffsetForCharacter(const PP_TextRun_Dev* text, uint32_t char_offset) { - WebTextRun run; - if (!PPTextRunToWebTextRun(text, &run)) - return -1; - if (char_offset >= run.text.length()) - return -1; - - WebFloatRect rect = font_->selectionRectForText( - run, WebFloatPoint(0.0f, 0.0f), font_->height(), 0, char_offset); - return static_cast<int>(rect.width); + int32_t result = -1; + WebKitForwarding::Font::TextRun run; + if (PPTextRunToTextRun(text, &run)) { + font_forwarding_->PixelOffsetForCharacter(NULL, run, char_offset, &result); + } + return result; } } // namespace ppapi diff --git a/webkit/plugins/ppapi/ppb_font_impl.h b/webkit/plugins/ppapi/ppb_font_impl.h index 368b935..c951327 100644 --- a/webkit/plugins/ppapi/ppb_font_impl.h +++ b/webkit/plugins/ppapi/ppb_font_impl.h @@ -8,6 +8,8 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" #include "ppapi/c/dev/ppb_font_dev.h" +#include "ppapi/shared_impl/webkit_forwarding.h" +#include "ppapi/thunk/ppb_font_api.h" #include "webkit/plugins/ppapi/resource.h" namespace WebKit { @@ -19,7 +21,8 @@ namespace ppapi { class PluginInstance; -class PPB_Font_Impl : public Resource { +class PPB_Font_Impl : public Resource, + public ::ppapi::thunk::PPB_Font_API { public: PPB_Font_Impl(PluginInstance* instance, const PP_FontDescription_Dev& desc); virtual ~PPB_Font_Impl(); @@ -28,26 +31,29 @@ class PPB_Font_Impl : public Resource { // the plugin. static const PPB_Font_Dev* GetInterface(); + // ResourceObjectBase. + virtual ::ppapi::thunk::PPB_Font_API* AsFont_API() OVERRIDE; + // Resource overrides. - virtual PPB_Font_Impl* AsPPB_Font_Impl(); + virtual PPB_Font_Impl* AsPPB_Font_Impl() OVERRIDE; // PPB_Font implementation. - bool Describe(PP_FontDescription_Dev* description, - PP_FontMetrics_Dev* metrics); - bool DrawTextAt(PP_Resource image_data, - const PP_TextRun_Dev* text, - const PP_Point* position, - uint32_t color, - const PP_Rect* clip, - bool image_data_is_opaque); - int32_t MeasureText(const PP_TextRun_Dev* text); + PP_Bool Describe(PP_FontDescription_Dev* description, + PP_FontMetrics_Dev* metrics) OVERRIDE; + 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; + int32_t MeasureText(const PP_TextRun_Dev* text) OVERRIDE; uint32_t CharacterOffsetForPixel(const PP_TextRun_Dev* text, - int32_t pixel_position); + int32_t pixel_position) OVERRIDE; int32_t PixelOffsetForCharacter(const PP_TextRun_Dev* text, - uint32_t char_offset); + uint32_t char_offset) OVERRIDE; private: - scoped_ptr<WebKit::WebFont> font_; + scoped_ptr<pp::shared_impl::WebKitForwarding::Font> font_forwarding_; DISALLOW_COPY_AND_ASSIGN(PPB_Font_Impl); }; diff --git a/webkit/plugins/ppapi/resource_creation_impl.cc b/webkit/plugins/ppapi/resource_creation_impl.cc index 674aee1..6308cc2 100644 --- a/webkit/plugins/ppapi/resource_creation_impl.cc +++ b/webkit/plugins/ppapi/resource_creation_impl.cc @@ -5,7 +5,9 @@ #include "webkit/plugins/ppapi/resource_creation_impl.h" #include "ppapi/c/pp_size.h" +#include "ppapi/shared_impl/font_impl.h" #include "webkit/plugins/ppapi/common.h" +#include "webkit/plugins/ppapi/ppb_font_impl.h" #include "webkit/plugins/ppapi/ppb_graphics_2d_impl.h" #include "webkit/plugins/ppapi/ppb_image_data_impl.h" @@ -23,6 +25,20 @@ ResourceCreationImpl::AsResourceCreation() { return this; } +PP_Resource ResourceCreationImpl::CreateFontObject( + PP_Instance pp_instance, + const PP_FontDescription_Dev* description) { + PluginInstance* instance = ResourceTracker::Get()->GetInstance(pp_instance); + if (!instance) + return 0; + + if (!pp::shared_impl::FontImpl::IsPPFontDescriptionValid(*description)) + return 0; + + scoped_refptr<PPB_Font_Impl> font(new PPB_Font_Impl(instance, *description)); + return font->GetReference(); +} + PP_Resource ResourceCreationImpl::CreateGraphics2D( PP_Instance pp_instance, const PP_Size& size, diff --git a/webkit/plugins/ppapi/resource_creation_impl.h b/webkit/plugins/ppapi/resource_creation_impl.h index 4d89715..2e31928 100644 --- a/webkit/plugins/ppapi/resource_creation_impl.h +++ b/webkit/plugins/ppapi/resource_creation_impl.h @@ -22,6 +22,9 @@ class ResourceCreationImpl : public ::ppapi::shared_impl::FunctionGroupBase, virtual ::ppapi::thunk::ResourceCreationAPI* AsResourceCreation(); // ResourceCreationAPI implementation. + 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/webkit/plugins/ppapi/webkit_forwarding_impl.cc b/webkit/plugins/ppapi/webkit_forwarding_impl.cc new file mode 100644 index 0000000..8c79e77 --- /dev/null +++ b/webkit/plugins/ppapi/webkit_forwarding_impl.cc @@ -0,0 +1,242 @@ +// 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 "webkit/plugins/ppapi/webkit_forwarding_impl.h" + +#include "base/scoped_ptr.h" +#include "base/synchronization/waitable_event.h" +#include "base/utf_string_conversions.h" +#include "ppapi/c/dev/ppb_font_dev.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/pp_rect.h" +#include "skia/ext/platform_canvas.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebCanvas.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebFont.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebFontDescription.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebFloatPoint.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebFloatRect.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebTextRun.h" +#include "webkit/glue/webkit_glue.h" + +using pp::shared_impl::WebKitForwarding; +using WebKit::WebCanvas; +using WebKit::WebFloatPoint; +using WebKit::WebFloatRect; +using WebKit::WebFont; +using WebKit::WebFontDescription; +using WebKit::WebRect; +using WebKit::WebTextRun; + +namespace webkit { +namespace ppapi { + +namespace { + +// The PP_* version lacks "None", so is just one value shifted from the +// WebFontDescription version. These values are checked in +// PPFontDescToWebFontDesc to make sure the conversion is correct. This is a +// macro so it can also be used in the COMPILE_ASSERTS. +#define PP_FONTFAMILY_TO_WEB_FONTFAMILY(f) \ + static_cast<WebFontDescription::GenericFamily>(f + 1) + +// Assumes the given PP_FontDescription has been validated. +WebFontDescription PPFontDescToWebFontDesc(const PP_FontDescription_Dev& font, + const std::string& face) { + // Verify that the enums match so we can just static cast. + COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight100) == + static_cast<int>(PP_FONTWEIGHT_100), + FontWeight100); + COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight900) == + static_cast<int>(PP_FONTWEIGHT_900), + FontWeight900); + COMPILE_ASSERT(WebFontDescription::GenericFamilyStandard == + PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_DEFAULT), + StandardFamily); + COMPILE_ASSERT(WebFontDescription::GenericFamilySerif == + PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_SERIF), + SerifFamily); + COMPILE_ASSERT(WebFontDescription::GenericFamilySansSerif == + PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_SANSSERIF), + SansSerifFamily); + COMPILE_ASSERT(WebFontDescription::GenericFamilyMonospace == + PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_MONOSPACE), + MonospaceFamily); + + WebFontDescription result; + result.family = UTF8ToUTF16(face); + result.genericFamily = PP_FONTFAMILY_TO_WEB_FONTFAMILY(font.family); + result.size = static_cast<float>(font.size); + result.italic = font.italic != PP_FALSE; + result.smallCaps = font.small_caps != PP_FALSE; + result.weight = static_cast<WebFontDescription::Weight>(font.weight); + result.letterSpacing = static_cast<short>(font.letter_spacing); + result.wordSpacing = static_cast<short>(font.word_spacing); + return result; +} + +WebTextRun TextRunToWebTextRun(const WebKitForwarding::Font::TextRun& run) { + return WebTextRun(UTF8ToUTF16(run.text), + run.rtl != PP_FALSE, + run.override_direction != PP_FALSE); +} + +// FontImpl -------------------------------------------------------------------- + +class FontImpl : public WebKitForwarding::Font { + public: + FontImpl(const PP_FontDescription_Dev& desc, + const std::string& desc_face); + virtual ~FontImpl(); + + virtual void Describe(base::WaitableEvent* event, + PP_FontDescription_Dev* description, + std::string* face, + PP_FontMetrics_Dev* metrics, + PP_Bool* result) OVERRIDE; + virtual void DrawTextAt(base::WaitableEvent* event, + const DrawTextParams& params) OVERRIDE; + virtual void MeasureText(base::WaitableEvent* event, + const TextRun& text, + int32_t* result) OVERRIDE; + virtual void CharacterOffsetForPixel(base::WaitableEvent* event, + const TextRun& text, + int32_t pixel_position, + uint32_t* result) OVERRIDE; + virtual void PixelOffsetForCharacter(base::WaitableEvent* event, + const TextRun& text, + uint32_t char_offset, + int32_t* result) OVERRIDE; + + private: + scoped_ptr<WebFont> font_; + + DISALLOW_COPY_AND_ASSIGN(FontImpl); +}; + +FontImpl::FontImpl(const PP_FontDescription_Dev& desc, + const std::string& desc_face) { + WebFontDescription web_font_desc = PPFontDescToWebFontDesc(desc, desc_face); + font_.reset(WebFont::create(web_font_desc)); +} + +FontImpl::~FontImpl() { +} + +void FontImpl::Describe(base::WaitableEvent* event, + PP_FontDescription_Dev* description, + std::string* face, + PP_FontMetrics_Dev* metrics, + PP_Bool* result) { + if (description->face.type != PP_VARTYPE_UNDEFINED) { + *result = PP_FALSE; + } else { + WebFontDescription web_desc = font_->fontDescription(); + + // While converting the other way in PPFontDescToWebFontDesc we validated + // that the enums can be casted. + description->face = PP_MakeUndefined(); + description->family = + static_cast<PP_FontFamily_Dev>(web_desc.genericFamily); + description->size = static_cast<uint32_t>(web_desc.size); + description->weight = static_cast<PP_FontWeight_Dev>(web_desc.weight); + description->italic = web_desc.italic ? PP_TRUE : PP_FALSE; + description->small_caps = web_desc.smallCaps ? PP_TRUE : PP_FALSE; + + *face = UTF16ToUTF8(web_desc.family); + + metrics->height = font_->height(); + metrics->ascent = font_->ascent(); + metrics->descent = font_->descent(); + metrics->line_spacing = font_->lineSpacing(); + metrics->x_height = static_cast<int32_t>(font_->xHeight()); + + *result = PP_TRUE; + } + if (event) + event->Signal(); +} + +void FontImpl::DrawTextAt(base::WaitableEvent* event, + const DrawTextParams& params) { + WebTextRun run = TextRunToWebTextRun(params.text); + + // Convert position and clip. + WebFloatPoint web_position(static_cast<float>(params.position->x), + static_cast<float>(params.position->y)); + WebRect web_clip; + if (!params.clip) { + // Use entire canvas. SkCanvas doesn't have a size on it, so we just use + // the current clip bounds. + SkRect skclip; + params.destination->getClipBounds(&skclip); + web_clip = WebRect(skclip.fLeft, skclip.fTop, skclip.fRight - skclip.fLeft, + skclip.fBottom - skclip.fTop); + } else { + web_clip = WebRect(params.clip->point.x, params.clip->point.y, + params.clip->size.width, params.clip->size.height); + } + + font_->drawText(webkit_glue::ToWebCanvas(params.destination), run, + web_position, params.color, web_clip, + params.image_data_is_opaque == PP_TRUE); + if (event) + event->Signal(); +} + +void FontImpl::MeasureText(base::WaitableEvent* event, + const TextRun& text, int32_t* result) { + *result = font_->calculateWidth(TextRunToWebTextRun(text)); + if (event) + event->Signal(); +} + +void FontImpl::CharacterOffsetForPixel(base::WaitableEvent* event, + const TextRun& text, + int32_t pixel_position, + uint32_t* result) { + *result = static_cast<uint32_t>(font_->offsetForPosition( + TextRunToWebTextRun(text), static_cast<float>(pixel_position))); + if (event) + event->Signal(); +} + +void FontImpl::PixelOffsetForCharacter(base::WaitableEvent* event, + const TextRun& text, + uint32_t char_offset, + int32_t* result) { + WebTextRun run = TextRunToWebTextRun(text); + if (char_offset >= run.text.length()) { + *result = -1; + } else { + WebFloatRect rect = font_->selectionRectForText( + run, WebFloatPoint(0.0f, 0.0f), font_->height(), 0, char_offset); + *result = static_cast<int>(rect.width); + } + if (event) + event->Signal(); +} + +} // namespace + +// WebKitForwardingImpl -------------------------------------------------------- + +WebKitForwardingImpl::WebKitForwardingImpl() { +} + +WebKitForwardingImpl::~WebKitForwardingImpl() { +} + +void WebKitForwardingImpl::CreateFontForwarding( + base::WaitableEvent* event, + const PP_FontDescription_Dev& desc, + const std::string& desc_face, + Font** result) { + *result = new FontImpl(desc, desc_face); + if (event) + event->Signal(); +} + +} // namespace ppapi +} // namespace webkit diff --git a/webkit/plugins/ppapi/webkit_forwarding_impl.h b/webkit/plugins/ppapi/webkit_forwarding_impl.h new file mode 100644 index 0000000..3914495 --- /dev/null +++ b/webkit/plugins/ppapi/webkit_forwarding_impl.h @@ -0,0 +1,24 @@ +// 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" + +#include "base/compiler_specific.h" + +namespace webkit { +namespace ppapi { + +class WebKitForwardingImpl : public pp::shared_impl::WebKitForwarding { + public: + WebKitForwardingImpl(); + virtual ~WebKitForwardingImpl(); + + virtual void CreateFontForwarding(base::WaitableEvent* event, + const PP_FontDescription_Dev& desc, + const std::string& desc_face, + Font** result) OVERRIDE; +}; + +} // namespace ppapi +} // namespace webkit |