diff options
Diffstat (limited to 'ppapi/proxy/ppb_font_proxy.cc')
-rw-r--r-- | ppapi/proxy/ppb_font_proxy.cc | 182 |
1 files changed, 180 insertions, 2 deletions
diff --git a/ppapi/proxy/ppb_font_proxy.cc b/ppapi/proxy/ppb_font_proxy.cc index b12c22e..49d3892 100644 --- a/ppapi/proxy/ppb_font_proxy.cc +++ b/ppapi/proxy/ppb_font_proxy.cc @@ -4,18 +4,46 @@ #include "ppapi/proxy/ppb_font_proxy.h" +#include "base/bind.h" +#include "base/debug/trace_event.h" #include "ppapi/c/dev/ppb_font_dev.h" #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_globals.h" #include "ppapi/proxy/plugin_proxy_delegate.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppb_image_data_proxy.h" +#include "ppapi/proxy/serialized_var.h" +#include "ppapi/shared_impl/ppapi_preferences.h" +#include "ppapi/shared_impl/resource.h" #include "ppapi/shared_impl/var.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_image_data_api.h" +#include "ppapi/thunk/thunk.h" +using ppapi::thunk::EnterResourceNoLock; +using ppapi::thunk::PPB_Font_API; using ppapi::thunk::PPB_Font_FunctionAPI; +using ppapi::thunk::PPB_ImageData_API; namespace ppapi { namespace proxy { +namespace { + +bool PPTextRunToTextRun(const PP_TextRun_Dev* run, + WebKitForwarding::Font::TextRun* output) { + StringVar* str = StringVar::FromPPVar(run->text); + if (!str) + return false; + + output->text = str->value(); + output->rtl = PP_ToBool(run->rtl); + output->override_direction = PP_ToBool(run->override_direction); + return true; +} + +} // namespace + PPB_Font_Proxy::PPB_Font_Proxy(Dispatcher* dispatcher) : InterfaceProxy(dispatcher) { } @@ -27,8 +55,6 @@ PPB_Font_FunctionAPI* PPB_Font_Proxy::AsPPB_Font_FunctionAPI() { return this; } -// TODO(ananta) -// This needs to be wired up to the PPAPI plugin code. PP_Var PPB_Font_Proxy::GetFontFamilies(PP_Instance instance) { PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); if (!dispatcher) @@ -50,5 +76,157 @@ bool PPB_Font_Proxy::OnMessageReceived(const IPC::Message& msg) { return false; } +Font::Font(const HostResource& resource, + const PP_FontDescription_Dev& desc) + : Resource(resource), + webkit_event_(false, false), + font_forwarding_(NULL) { + TRACE_EVENT0("ppapi proxy", "Font::Font"); + StringVar* face = StringVar::FromPPVar(desc.face); + + PluginDispatcher* dispatcher = PluginDispatcher::GetForResource(this); + if (!dispatcher) + return; + WebKitForwarding* forwarding = + PluginGlobals::Get()->plugin_proxy_delegate()->GetWebKitForwarding(); + + RunOnWebKitThread(true, + base::Bind(&WebKitForwarding::CreateFontForwarding, + base::Unretained(forwarding), + &webkit_event_, desc, + face ? face->value() : std::string(), + dispatcher->preferences(), + &font_forwarding_)); +} + +Font::~Font() { + if (font_forwarding_) { + RunOnWebKitThread(false, + base::Bind(&DeleteFontForwarding, font_forwarding_)); + } +} + +PPB_Font_API* Font::AsPPB_Font_API() { + return this; +} + +PP_Bool Font::Describe(PP_FontDescription_Dev* description, + PP_FontMetrics_Dev* metrics) { + TRACE_EVENT0("ppapi proxy", "Font::Describe"); + std::string face; + PP_Bool result = PP_FALSE; + if (font_forwarding_) { + RunOnWebKitThread(true, + base::Bind(&WebKitForwarding::Font::Describe, + base::Unretained(font_forwarding_), + &webkit_event_, description, &face, metrics, + &result)); + } + + if (PP_ToBool(result)) + description->face = StringVar::StringToPPVar(face); + else + description->face = PP_MakeUndefined(); + 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) { + TRACE_EVENT0("ppapi proxy", "Font::DrawTextAt"); + if (!font_forwarding_) + return PP_FALSE; + + // Convert to an ImageData object. + EnterResourceNoLock<PPB_ImageData_API> enter(pp_image_data, true); + if (enter.failed()) + return PP_FALSE; + ImageData* image_data = static_cast<ImageData*>(enter.object()); + + 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. + } + + WebKitForwarding::Font::TextRun run; + if (!PPTextRunToTextRun(text, &run)) { + if (needs_unmapping) + image_data->Unmap(); + return PP_FALSE; + } + RunOnWebKitThread( + true, + base::Bind(&WebKitForwarding::Font::DrawTextAt, + base::Unretained(font_forwarding_), &webkit_event_, + WebKitForwarding::Font::DrawTextParams(canvas, run, position, + color, clip, + image_data_is_opaque))); + + if (needs_unmapping) + image_data->Unmap(); + return PP_TRUE; +} + +int32_t Font::MeasureText(const PP_TextRun_Dev* text) { + TRACE_EVENT0("ppapi proxy", "Font::MeasureText"); + WebKitForwarding::Font::TextRun run; + if (!font_forwarding_ || !PPTextRunToTextRun(text, &run)) + return -1; + int32_t result = -1; + RunOnWebKitThread(true, + base::Bind(&WebKitForwarding::Font::MeasureText, + base::Unretained(font_forwarding_), + &webkit_event_, run, &result)); + return result; +} + +uint32_t Font::CharacterOffsetForPixel(const PP_TextRun_Dev* text, + int32_t pixel_position) { + TRACE_EVENT0("ppapi proxy", "Font::CharacterOffsetForPixel"); + WebKitForwarding::Font::TextRun run; + if (!font_forwarding_ || !PPTextRunToTextRun(text, &run)) + return -1; + uint32_t result = -1; + RunOnWebKitThread(true, + base::Bind(&WebKitForwarding::Font::CharacterOffsetForPixel, + base::Unretained(font_forwarding_), + &webkit_event_, run, pixel_position, &result)); + return result; +} + +int32_t Font::PixelOffsetForCharacter(const PP_TextRun_Dev* text, + uint32_t char_offset) { + TRACE_EVENT0("ppapi proxy", "Font::PixelOffsetForCharacter"); + WebKitForwarding::Font::TextRun run; + if (!font_forwarding_ || !PPTextRunToTextRun(text, &run)) + return -1; + int32_t result = -1; + RunOnWebKitThread(true, + base::Bind(&WebKitForwarding::Font::PixelOffsetForCharacter, + base::Unretained(font_forwarding_), + &webkit_event_, run, char_offset, &result)); + return result; +} + +void Font::RunOnWebKitThread(bool blocking, const base::Closure& task) { + PluginGlobals::Get()->plugin_proxy_delegate()->PostToWebKitThread( + FROM_HERE, task); + if (blocking) + webkit_event_.Wait(); +} + +// static +void Font::DeleteFontForwarding(WebKitForwarding::Font* font_forwarding) { + delete font_forwarding; +} + } // namespace proxy } // namespace ppapi |