From cd781859e94bc4cedb35371cf4d6d1e161e87a11 Mon Sep 17 00:00:00 2001 From: "sadrul@chromium.org" Date: Fri, 20 Jan 2012 02:35:48 +0000 Subject: Revert 118385 since this seems to break mac-debug build. """ Remove the Webkit thread in the PPAPI plugin process and perform the text and font operations on the PPAPI main thread. This thread is now registered as the Webkit thread. Fixes performance issues seen in Flapper with text and font operations. It appears that the perf issues occur due to context switching between the main thread and the webkit thread. As per comments from Brett moving the font forwarding code inline to ppb_font_shared.cc. This file has been moved to ppapi/shared_impl/private as it now brings in a dependency on WebKit. The font creation has been wired up to the ResourceCreationAPI as suggested. BUG=110190 R=brettw Review URL: https://chromiumcodereview.appspot.com/9133015 TBR=ananta@chromium.org Review URL: https://chromiumcodereview.appspot.com/9150055 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@118399 0039d316-1c4b-4281-b951-d872f2087c98 --- webkit/plugins/ppapi/plugin_module.cc | 7 + webkit/plugins/ppapi/plugin_module.h | 6 + webkit/plugins/ppapi/ppb_flash_impl.cc | 2 +- webkit/plugins/ppapi/ppb_font_impl.cc | 142 +++++++++++- webkit/plugins/ppapi/ppb_font_impl.h | 43 +++- webkit/plugins/ppapi/ppb_graphics_2d_impl.cc | 6 +- webkit/plugins/ppapi/ppb_image_data_impl.cc | 4 - webkit/plugins/ppapi/ppb_image_data_impl.h | 3 +- webkit/plugins/ppapi/ppb_scrollbar_impl.cc | 2 +- webkit/plugins/ppapi/resource_creation_impl.cc | 10 +- webkit/plugins/ppapi/resource_helper.cc | 7 +- webkit/plugins/ppapi/resource_helper.h | 4 - webkit/plugins/ppapi/webkit_forwarding_impl.cc | 300 +++++++++++++++++++++++++ webkit/plugins/ppapi/webkit_forwarding_impl.h | 30 +++ 14 files changed, 530 insertions(+), 36 deletions(-) create mode 100644 webkit/plugins/ppapi/webkit_forwarding_impl.cc create mode 100644 webkit/plugins/ppapi/webkit_forwarding_impl.h (limited to 'webkit/plugins') diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc index 5ca81c8..c6af869 100644 --- a/webkit/plugins/ppapi/plugin_module.cc +++ b/webkit/plugins/ppapi/plugin_module.cc @@ -116,6 +116,7 @@ #include "webkit/plugins/ppapi/ppb_video_capture_impl.h" #include "webkit/plugins/ppapi/ppb_video_decoder_impl.h" #include "webkit/plugins/ppapi/ppb_video_layer_impl.h" +#include "webkit/plugins/ppapi/webkit_forwarding_impl.h" using ppapi::InputEventData; using ppapi::PpapiGlobals; @@ -590,6 +591,12 @@ PluginDelegate::PpapiBroker* PluginModule::GetBroker() { return broker_; } +::ppapi::WebKitForwarding* PluginModule::GetWebKitForwarding() { + if (!webkit_forwarding_.get()) + webkit_forwarding_.reset(new WebKitForwardingImpl); + return webkit_forwarding_.get(); +} + bool PluginModule::InitializeModule(const EntryPoints& entry_points) { DCHECK(!out_of_process_proxy_.get()) << "Don't call for proxied modules."; DCHECK(entry_points.initialize_module != NULL); diff --git a/webkit/plugins/ppapi/plugin_module.h b/webkit/plugins/ppapi/plugin_module.h index 928f8ac..7634268 100644 --- a/webkit/plugins/ppapi/plugin_module.h +++ b/webkit/plugins/ppapi/plugin_module.h @@ -141,6 +141,9 @@ class WEBKIT_PLUGINS_EXPORT PluginModule : void SetBroker(PluginDelegate::PpapiBroker* broker); PluginDelegate::PpapiBroker* GetBroker(); + // Retrieves the forwarding interface used for talking to WebKit. + ::ppapi::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 @@ -193,6 +196,9 @@ class WEBKIT_PLUGINS_EXPORT PluginModule : PP_Bool (*reserve_instance_id_)(PP_Module, PP_Instance); + // Lazily created by GetWebKitForwarding. + scoped_ptr< ::ppapi::WebKitForwarding> webkit_forwarding_; + DISALLOW_COPY_AND_ASSIGN(PluginModule); }; diff --git a/webkit/plugins/ppapi/ppb_flash_impl.cc b/webkit/plugins/ppapi/ppb_flash_impl.cc index c1133ba..c65fbcc 100644 --- a/webkit/plugins/ppapi/ppb_flash_impl.cc +++ b/webkit/plugins/ppapi/ppb_flash_impl.cc @@ -89,7 +89,7 @@ PP_Bool DrawGlyphs(PP_Instance, SkAutoUnref aur(typeface); // Set up the canvas. - SkCanvas* canvas = image_resource->GetPlatformCanvas(); + SkCanvas* canvas = image_resource->mapped_canvas(); SkAutoCanvasRestore acr(canvas, true); // Clip is applied in pixels before the transform. diff --git a/webkit/plugins/ppapi/ppb_font_impl.cc b/webkit/plugins/ppapi/ppb_font_impl.cc index c18106a..0c439d0 100644 --- a/webkit/plugins/ppapi/ppb_font_impl.cc +++ b/webkit/plugins/ppapi/ppb_font_impl.cc @@ -4,12 +4,148 @@ #include "webkit/plugins/ppapi/ppb_font_impl.h" +#include "ppapi/c/dev/ppb_font_dev.h" +#include "ppapi/shared_impl/ppapi_preferences.h" +#include "ppapi/shared_impl/ppb_font_shared.h" +#include "ppapi/shared_impl/var.h" +#include "ppapi/thunk/enter.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/resource_helper.h" +#include "webkit/plugins/ppapi/string.h" -namespace webkit { +using ppapi::StringVar; +using ppapi::thunk::EnterResource; +using ppapi::thunk::PPB_ImageData_API; +using ppapi::WebKitForwarding; +namespace webkit { namespace ppapi { +namespace { + +// Converts the given PP_TextRun to a TextRun, returning true on success. +// False means the input was invalid. +bool PPTextRunToTextRun(const PP_TextRun_Dev* run, + WebKitForwarding::Font::TextRun* output) { + StringVar* text_string = StringVar::FromPPVar(run->text); + if (!text_string) + return false; + + output->text = text_string->value(); + output->rtl = PPBoolToBool(run->rtl); + output->override_direction = PPBoolToBool(run->override_direction); + return true; +} + +} // namespace + +PPB_Font_Impl::PPB_Font_Impl(PP_Instance pp_instance, + const PP_FontDescription_Dev& desc) + : Resource(pp_instance) { + StringVar* face_name = StringVar::FromPPVar(desc.face); + + WebKitForwarding::Font* result = NULL; + PluginInstance* plugin_instance = ResourceHelper::GetPluginInstance(this); + if (plugin_instance) { + plugin_instance->module()->GetWebKitForwarding()->CreateFontForwarding( + NULL, desc, face_name ? face_name->value() : std::string(), + plugin_instance->delegate()->GetPreferences(), &result); + } + font_forwarding_.reset(result); +} + +PPB_Font_Impl::~PPB_Font_Impl() { +} + +// static +PP_Resource PPB_Font_Impl::Create(PP_Instance instance, + const PP_FontDescription_Dev& description) { + if (!::ppapi::PPB_Font_Shared::IsPPFontDescriptionValid(description)) + return 0; + return (new PPB_Font_Impl(instance, description))->GetReference(); +} + +::ppapi::thunk::PPB_Font_API* PPB_Font_Impl::AsPPB_Font_API() { + return this; +} + +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; + + PluginModule* plugin_module = ResourceHelper::GetPluginModule(this); + if (!plugin_module) + return PP_FALSE; + + // Convert the string. + description->face = StringVar::StringToPPVar(face); + return PP_TRUE; +} + +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. + EnterResource enter(image_data, true); + if (enter.failed()) + return PP_FALSE; + PPB_ImageData_Impl* image_resource = + static_cast(enter.object()); + + ImageDataAutoMapper mapper(image_resource); + if (!mapper.is_valid()) + return PP_FALSE; + + WebKitForwarding::Font::TextRun run; + if (!PPTextRunToTextRun(text, &run)) + return PP_FALSE; + + 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) { + 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) { + 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) { + int32_t result = -1; + WebKitForwarding::Font::TextRun run; + if (PPTextRunToTextRun(text, &run)) { + font_forwarding_->PixelOffsetForCharacter(NULL, run, char_offset, &result); + } + return result; +} + PPB_Font_FunctionImpl::PPB_Font_FunctionImpl(PluginInstance* instance) : instance_(instance) { } @@ -22,12 +158,10 @@ PPB_Font_FunctionImpl::AsFont_FunctionAPI() { return this; } -// TODO(ananta) -// We need to wire this up to the proxy. PP_Var PPB_Font_FunctionImpl::GetFontFamilies(PP_Instance instance) { return PP_MakeUndefined(); } } // namespace ppapi - } // namespace webkit + diff --git a/webkit/plugins/ppapi/ppb_font_impl.h b/webkit/plugins/ppapi/ppb_font_impl.h index c21b18e..4b9c7e0 100644 --- a/webkit/plugins/ppapi/ppb_font_impl.h +++ b/webkit/plugins/ppapi/ppb_font_impl.h @@ -6,9 +6,11 @@ #define WEBKIT_PLUGINS_PPAPI_PPB_FONT_IMPL_H_ #include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "ppapi/c/pp_instance.h" +#include "base/memory/scoped_ptr.h" +#include "ppapi/c/dev/ppb_font_dev.h" #include "ppapi/shared_impl/function_group_base.h" +#include "ppapi/shared_impl/resource.h" +#include "ppapi/shared_impl/webkit_forwarding.h" #include "ppapi/thunk/ppb_font_api.h" namespace webkit { @@ -16,6 +18,40 @@ namespace ppapi { class PluginInstance; +class PPB_Font_Impl : public ::ppapi::Resource, + public ::ppapi::thunk::PPB_Font_API { + public: + virtual ~PPB_Font_Impl(); + + static PP_Resource Create(PP_Instance instance, + const PP_FontDescription_Dev& description); + + // Resource. + virtual ::ppapi::thunk::PPB_Font_API* AsPPB_Font_API() OVERRIDE; + + // PPB_Font 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: + PPB_Font_Impl(PP_Instance instance, const PP_FontDescription_Dev& desc); + + scoped_ptr< ::ppapi::WebKitForwarding::Font> font_forwarding_; + + DISALLOW_COPY_AND_ASSIGN(PPB_Font_Impl); +}; + class PPB_Font_FunctionImpl : public ::ppapi::FunctionGroupBase, public ::ppapi::thunk::PPB_Font_FunctionAPI { public: @@ -35,7 +71,6 @@ class PPB_Font_FunctionImpl : public ::ppapi::FunctionGroupBase, }; } // namespace ppapi - -} // namespace webkit. +} // namespace webkit #endif // WEBKIT_PLUGINS_PPAPI_PPB_FONT_IMPL_H_ diff --git a/webkit/plugins/ppapi/ppb_graphics_2d_impl.cc b/webkit/plugins/ppapi/ppb_graphics_2d_impl.cc index ddfea5f..027e8eb 100644 --- a/webkit/plugins/ppapi/ppb_graphics_2d_impl.cc +++ b/webkit/plugins/ppapi/ppb_graphics_2d_impl.cc @@ -398,7 +398,7 @@ bool PPB_Graphics2D_Impl::ReadImageData(PP_Resource image, // Convert the image data if the format does not match. ConvertImageData(image_data_, src_irect, image_resource, dest_rect); } else { - skia::PlatformCanvas* dest_canvas = image_resource->GetPlatformCanvas(); + skia::PlatformCanvas* dest_canvas = image_resource->mapped_canvas(); // We want to replace the contents of the bitmap rather than blend. SkPaint paint; @@ -583,7 +583,7 @@ void PPB_Graphics2D_Impl::ExecutePaintImageData(PPB_ImageData_Impl* image, ConvertImageData(image, src_irect, image_data_, dest_rect); } else { // We're guaranteed to have a mapped canvas since we mapped it in Init(). - skia::PlatformCanvas* backing_canvas = image_data_->GetPlatformCanvas(); + skia::PlatformCanvas* backing_canvas = image_data_->mapped_canvas(); // We want to replace the contents of the bitmap rather than blend. SkPaint paint; @@ -596,7 +596,7 @@ void PPB_Graphics2D_Impl::ExecutePaintImageData(PPB_ImageData_Impl* image, void PPB_Graphics2D_Impl::ExecuteScroll(const gfx::Rect& clip, int dx, int dy, gfx::Rect* invalidated_rect) { - gfx::ScrollCanvas(image_data_->GetPlatformCanvas(), + gfx::ScrollCanvas(image_data_->mapped_canvas(), clip, gfx::Point(dx, dy)); *invalidated_rect = clip; } diff --git a/webkit/plugins/ppapi/ppb_image_data_impl.cc b/webkit/plugins/ppapi/ppb_image_data_impl.cc index fa30601..6563713 100644 --- a/webkit/plugins/ppapi/ppb_image_data_impl.cc +++ b/webkit/plugins/ppapi/ppb_image_data_impl.cc @@ -111,10 +111,6 @@ int32_t PPB_ImageData_Impl::GetSharedMemory(int* handle, return PP_OK; } -skia::PlatformCanvas* PPB_ImageData_Impl::GetPlatformCanvas() { - return mapped_canvas_.get(); -} - const SkBitmap* PPB_ImageData_Impl::GetMappedBitmap() const { if (!mapped_canvas_.get()) return NULL; diff --git a/webkit/plugins/ppapi/ppb_image_data_impl.h b/webkit/plugins/ppapi/ppb_image_data_impl.h index 817b238..64685d0 100644 --- a/webkit/plugins/ppapi/ppb_image_data_impl.h +++ b/webkit/plugins/ppapi/ppb_image_data_impl.h @@ -63,8 +63,9 @@ class PPB_ImageData_Impl : public ::ppapi::Resource, virtual void* Map() OVERRIDE; virtual void Unmap() OVERRIDE; virtual int32_t GetSharedMemory(int* handle, uint32_t* byte_count) OVERRIDE; - virtual skia::PlatformCanvas* GetPlatformCanvas() OVERRIDE; + // The mapped bitmap and canvas will be NULL if the image is not mapped. + skia::PlatformCanvas* mapped_canvas() const { return mapped_canvas_.get(); } const SkBitmap* GetMappedBitmap() const; // Swaps the guts of this image data with another. diff --git a/webkit/plugins/ppapi/ppb_scrollbar_impl.cc b/webkit/plugins/ppapi/ppb_scrollbar_impl.cc index 3e3f2e9..97b80ff 100644 --- a/webkit/plugins/ppapi/ppb_scrollbar_impl.cc +++ b/webkit/plugins/ppapi/ppb_scrollbar_impl.cc @@ -134,7 +134,7 @@ void PPB_Scrollbar_Impl::ScrollBy(PP_ScrollBy_Dev unit, int32_t multiplier) { PP_Bool PPB_Scrollbar_Impl::PaintInternal(const gfx::Rect& rect, PPB_ImageData_Impl* image) { ImageDataAutoMapper mapper(image); - skia::PlatformCanvas* canvas = image->GetPlatformCanvas(); + skia::PlatformCanvas* canvas = image->mapped_canvas(); if (!canvas || !scrollbar_.get()) return PP_FALSE; scrollbar_->paint(webkit_glue::ToWebCanvas(canvas), rect); diff --git a/webkit/plugins/ppapi/resource_creation_impl.cc b/webkit/plugins/ppapi/resource_creation_impl.cc index b1480a0..1f3943b 100644 --- a/webkit/plugins/ppapi/resource_creation_impl.cc +++ b/webkit/plugins/ppapi/resource_creation_impl.cc @@ -6,7 +6,6 @@ #include "ppapi/c/pp_size.h" #include "ppapi/shared_impl/ppb_audio_config_shared.h" -#include "ppapi/shared_impl/private/ppb_font_shared.h" #include "ppapi/shared_impl/ppb_input_event_shared.h" #include "ppapi/shared_impl/ppb_resource_array_shared.h" #include "ppapi/shared_impl/var.h" @@ -22,6 +21,7 @@ #include "webkit/plugins/ppapi/ppb_file_system_impl.h" #include "webkit/plugins/ppapi/ppb_flash_menu_impl.h" #include "webkit/plugins/ppapi/ppb_flash_net_connector_impl.h" +#include "webkit/plugins/ppapi/ppb_font_impl.h" #include "webkit/plugins/ppapi/ppb_graphics_2d_impl.h" #include "webkit/plugins/ppapi/ppb_graphics_3d_impl.h" #include "webkit/plugins/ppapi/ppb_image_data_impl.h" @@ -35,7 +35,6 @@ #include "webkit/plugins/ppapi/ppb_video_decoder_impl.h" #include "webkit/plugins/ppapi/ppb_video_layer_impl.h" #include "webkit/plugins/ppapi/ppb_websocket_impl.h" -#include "webkit/plugins/ppapi/resource_helper.h" using ppapi::InputEventData; using ppapi::PPB_InputEvent_Shared; @@ -143,12 +142,7 @@ PP_Resource ResourceCreationImpl::CreateFlashNetConnector( PP_Resource ResourceCreationImpl::CreateFontObject( PP_Instance instance, const PP_FontDescription_Dev* description) { - PluginInstance* plugin_instance = - ResourceHelper::PPInstanceToPluginInstance(instance); - if (!plugin_instance) - return 0; - return ::ppapi::PPB_Font_Shared::CreateAsImpl( - instance, *description, plugin_instance->delegate()->GetPreferences()); + return PPB_Font_Impl::Create(instance, *description); } PP_Resource ResourceCreationImpl::CreateGraphics2D( diff --git a/webkit/plugins/ppapi/resource_helper.cc b/webkit/plugins/ppapi/resource_helper.cc index 0807e2e..1959961 100644 --- a/webkit/plugins/ppapi/resource_helper.cc +++ b/webkit/plugins/ppapi/resource_helper.cc @@ -17,12 +17,7 @@ namespace ppapi { // static PluginInstance* ResourceHelper::GetPluginInstance( const ::ppapi::Resource* resource) { - return PPInstanceToPluginInstance(resource->pp_instance()); -} - -PluginInstance* ResourceHelper::PPInstanceToPluginInstance( - PP_Instance instance) { - return HostGlobals::Get()->GetInstance(instance); + return HostGlobals::Get()->GetInstance(resource->pp_instance()); } PluginModule* ResourceHelper::GetPluginModule( diff --git a/webkit/plugins/ppapi/resource_helper.h b/webkit/plugins/ppapi/resource_helper.h index cca66f0..1f245a1 100644 --- a/webkit/plugins/ppapi/resource_helper.h +++ b/webkit/plugins/ppapi/resource_helper.h @@ -6,7 +6,6 @@ #define WEBKIT_PLUGINS_PPAPI_RESOURCE_HELPER_H_ #include "base/basictypes.h" -#include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_resource.h" #include "webkit/plugins/webkit_plugins_export.h" @@ -41,9 +40,6 @@ class ResourceHelper { // resource has outlived its instance. static PluginDelegate* GetPluginDelegate(const ::ppapi::Resource* resource); - // Returns the instance implementation object for the pp_instance. - static PluginInstance* PPInstanceToPluginInstance(PP_Instance instance); - private: DISALLOW_IMPLICIT_CONSTRUCTORS(ResourceHelper); }; diff --git a/webkit/plugins/ppapi/webkit_forwarding_impl.cc b/webkit/plugins/ppapi/webkit_forwarding_impl.cc new file mode 100644 index 0000000..967919b --- /dev/null +++ b/webkit/plugins/ppapi/webkit_forwarding_impl.cc @@ -0,0 +1,300 @@ +// 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 + +#include "base/debug/trace_event.h" +#include "base/memory/scoped_ptr.h" +#include "base/string_util.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 "ppapi/shared_impl/ppapi_preferences.h" +#include "skia/ext/platform_canvas.h" +#include "third_party/skia/include/core/SkRect.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/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/platform/WebRect.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatPoint.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatRect.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebTextRun.h" +#include "webkit/glue/webkit_glue.h" + +using ::ppapi::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(f + 1) + +// Assumes the given PP_FontDescription has been validated. +WebFontDescription PPFontDescToWebFontDesc(const PP_FontDescription_Dev& font, + const std::string& face, + const ::ppapi::Preferences& prefs) { + // Verify that the enums match so we can just static cast. + COMPILE_ASSERT(static_cast(WebFontDescription::Weight100) == + static_cast(PP_FONTWEIGHT_100), + FontWeight100); + COMPILE_ASSERT(static_cast(WebFontDescription::Weight900) == + static_cast(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; + string16 resolved_family; + if (face.empty()) { + // Resolve the generic family. + switch (font.family) { + case PP_FONTFAMILY_SERIF: + resolved_family = prefs.serif_font_family; + break; + case PP_FONTFAMILY_SANSSERIF: + resolved_family = prefs.sans_serif_font_family; + break; + case PP_FONTFAMILY_MONOSPACE: + resolved_family = prefs.fixed_font_family; + break; + case PP_FONTFAMILY_DEFAULT: + default: + resolved_family = prefs.standard_font_family; + break; + } + } else { + // Use the exact font. + resolved_family = UTF8ToUTF16(face); + } + result.family = resolved_family; + + result.genericFamily = PP_FONTFAMILY_TO_WEB_FONTFAMILY(font.family); + + if (font.size == 0) { + // Resolve the default font size, using the resolved family to see if + // we should use the fixed or regular font size. It's difficult at this + // level to detect if the requested font is fixed width, so we only apply + // the alternate font size to the default fixed font family. + if (StringToLowerASCII(resolved_family) == + StringToLowerASCII(prefs.fixed_font_family)) + result.size = static_cast(prefs.default_fixed_font_size); + else + result.size = static_cast(prefs.default_font_size); + } else { + // Use the exact size. + result.size = static_cast(font.size); + } + + result.italic = font.italic != PP_FALSE; + result.smallCaps = font.small_caps != PP_FALSE; + result.weight = static_cast(font.weight); + result.letterSpacing = static_cast(font.letter_spacing); + result.wordSpacing = static_cast(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, + const ::ppapi::Preferences& prefs); + 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 font_; + + DISALLOW_COPY_AND_ASSIGN(FontImpl); +}; + +FontImpl::FontImpl(const PP_FontDescription_Dev& desc, + const std::string& desc_face, + const ::ppapi::Preferences& prefs) { + WebFontDescription web_font_desc = PPFontDescToWebFontDesc(desc, desc_face, + prefs); + 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) { + TRACE_EVENT0("ppapi WebKit thread", "FontImpl::Describe"); + 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(web_desc.genericFamily); + description->size = static_cast(web_desc.size); + description->weight = static_cast(web_desc.weight); + description->italic = web_desc.italic ? PP_TRUE : PP_FALSE; + description->small_caps = web_desc.smallCaps ? PP_TRUE : PP_FALSE; + description->letter_spacing = static_cast(web_desc.letterSpacing); + description->word_spacing = static_cast(web_desc.wordSpacing); + + *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(font_->xHeight()); + + *result = PP_TRUE; + } + if (event) + event->Signal(); +} + +void FontImpl::DrawTextAt(base::WaitableEvent* event, + const DrawTextParams& params) { + TRACE_EVENT0("ppapi WebKit thread", "FontImpl::DrawTextAt"); + WebTextRun run = TextRunToWebTextRun(params.text); + + // Convert position and clip. + WebFloatPoint web_position(static_cast(params.position->x), + static_cast(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) { + TRACE_EVENT0("ppapi WebKit thread", "FontImpl::MeasureText"); + *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) { + TRACE_EVENT0("ppapi WebKit thread", "FontImpl::CharacterOffsetForPixel"); + *result = static_cast(font_->offsetForPosition( + TextRunToWebTextRun(text), static_cast(pixel_position))); + if (event) + event->Signal(); +} + +void FontImpl::PixelOffsetForCharacter(base::WaitableEvent* event, + const TextRun& text, + uint32_t char_offset, + int32_t* result) { + TRACE_EVENT0("ppapi WebKit thread", "FontImpl::PixelOffsetForCharacter"); + 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(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, + const ::ppapi::Preferences& prefs, + Font** result) { + TRACE_EVENT0("ppapi WebKit thread", + "WebKitForwardingImpl::CreateFontForwarding"); + *result = new FontImpl(desc, desc_face, prefs); + 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..ee39754 --- /dev/null +++ b/webkit/plugins/ppapi/webkit_forwarding_impl.h @@ -0,0 +1,30 @@ +// 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" +#include "webkit/plugins/webkit_plugins_export.h" + +namespace ppapi { +struct Preferences; +} + +namespace webkit { +namespace ppapi { + +class WebKitForwardingImpl : public ::ppapi::WebKitForwarding { + public: + WEBKIT_PLUGINS_EXPORT WebKitForwardingImpl(); + WEBKIT_PLUGINS_EXPORT virtual ~WebKitForwardingImpl(); + + virtual void CreateFontForwarding(base::WaitableEvent* event, + const PP_FontDescription_Dev& desc, + const std::string& desc_face, + const ::ppapi::Preferences& prefs, + Font** result) OVERRIDE; +}; + +} // namespace ppapi +} // namespace webkit -- cgit v1.1