| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ppapi/proxy/ppb_font_proxy.h" | 5 #include "ppapi/proxy/ppb_font_proxy.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | |
| 8 #include "base/debug/trace_event.h" | |
| 9 #include "ppapi/c/dev/ppb_font_dev.h" | 7 #include "ppapi/c/dev/ppb_font_dev.h" |
| 10 #include "ppapi/proxy/plugin_dispatcher.h" | 8 #include "ppapi/proxy/plugin_dispatcher.h" |
| 11 #include "ppapi/proxy/plugin_globals.h" | 9 #include "ppapi/proxy/plugin_globals.h" |
| 12 #include "ppapi/proxy/plugin_proxy_delegate.h" | 10 #include "ppapi/proxy/plugin_proxy_delegate.h" |
| 13 #include "ppapi/proxy/ppapi_messages.h" | 11 #include "ppapi/proxy/ppapi_messages.h" |
| 14 #include "ppapi/proxy/ppb_image_data_proxy.h" | |
| 15 #include "ppapi/proxy/serialized_var.h" | |
| 16 #include "ppapi/shared_impl/ppapi_preferences.h" | |
| 17 #include "ppapi/shared_impl/resource.h" | |
| 18 #include "ppapi/shared_impl/var.h" | 12 #include "ppapi/shared_impl/var.h" |
| 19 #include "ppapi/thunk/enter.h" | |
| 20 #include "ppapi/thunk/ppb_image_data_api.h" | |
| 21 #include "ppapi/thunk/thunk.h" | |
| 22 | 13 |
| 23 using ppapi::thunk::EnterResourceNoLock; | |
| 24 using ppapi::thunk::PPB_Font_API; | |
| 25 using ppapi::thunk::PPB_Font_FunctionAPI; | 14 using ppapi::thunk::PPB_Font_FunctionAPI; |
| 26 using ppapi::thunk::PPB_ImageData_API; | |
| 27 | 15 |
| 28 namespace ppapi { | 16 namespace ppapi { |
| 29 namespace proxy { | 17 namespace proxy { |
| 30 | 18 |
| 31 namespace { | |
| 32 | |
| 33 bool PPTextRunToTextRun(const PP_TextRun_Dev* run, | |
| 34 WebKitForwarding::Font::TextRun* output) { | |
| 35 StringVar* str = StringVar::FromPPVar(run->text); | |
| 36 if (!str) | |
| 37 return false; | |
| 38 | |
| 39 output->text = str->value(); | |
| 40 output->rtl = PP_ToBool(run->rtl); | |
| 41 output->override_direction = PP_ToBool(run->override_direction); | |
| 42 return true; | |
| 43 } | |
| 44 | |
| 45 } // namespace | |
| 46 | |
| 47 PPB_Font_Proxy::PPB_Font_Proxy(Dispatcher* dispatcher) | 19 PPB_Font_Proxy::PPB_Font_Proxy(Dispatcher* dispatcher) |
| 48 : InterfaceProxy(dispatcher) { | 20 : InterfaceProxy(dispatcher) { |
| 49 } | 21 } |
| 50 | 22 |
| 51 PPB_Font_Proxy::~PPB_Font_Proxy() { | 23 PPB_Font_Proxy::~PPB_Font_Proxy() { |
| 52 } | 24 } |
| 53 | 25 |
| 54 PPB_Font_FunctionAPI* PPB_Font_Proxy::AsPPB_Font_FunctionAPI() { | 26 PPB_Font_FunctionAPI* PPB_Font_Proxy::AsPPB_Font_FunctionAPI() { |
| 55 return this; | 27 return this; |
| 56 } | 28 } |
| 57 | 29 |
| 30 // TODO(ananta) |
| 31 // This needs to be wired up to the PPAPI plugin code. |
| 58 PP_Var PPB_Font_Proxy::GetFontFamilies(PP_Instance instance) { | 32 PP_Var PPB_Font_Proxy::GetFontFamilies(PP_Instance instance) { |
| 59 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); | 33 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); |
| 60 if (!dispatcher) | 34 if (!dispatcher) |
| 61 return PP_MakeUndefined(); | 35 return PP_MakeUndefined(); |
| 62 | 36 |
| 63 // Assume the font families don't change, so we can cache the result globally. | 37 // Assume the font families don't change, so we can cache the result globally. |
| 64 CR_DEFINE_STATIC_LOCAL(std::string, families, ()); | 38 CR_DEFINE_STATIC_LOCAL(std::string, families, ()); |
| 65 if (families.empty()) { | 39 if (families.empty()) { |
| 66 PluginGlobals::Get()->plugin_proxy_delegate()->SendToBrowser( | 40 PluginGlobals::Get()->plugin_proxy_delegate()->SendToBrowser( |
| 67 new PpapiHostMsg_PPBFont_GetFontFamilies(&families)); | 41 new PpapiHostMsg_PPBFont_GetFontFamilies(&families)); |
| 68 } | 42 } |
| 69 | 43 |
| 70 return StringVar::StringToPPVar(families); | 44 return StringVar::StringToPPVar(families); |
| 71 } | 45 } |
| 72 | 46 |
| 73 bool PPB_Font_Proxy::OnMessageReceived(const IPC::Message& msg) { | 47 bool PPB_Font_Proxy::OnMessageReceived(const IPC::Message& msg) { |
| 74 // There aren't any font messages. | 48 // There aren't any font messages. |
| 75 NOTREACHED(); | 49 NOTREACHED(); |
| 76 return false; | 50 return false; |
| 77 } | 51 } |
| 78 | 52 |
| 79 Font::Font(const HostResource& resource, | |
| 80 const PP_FontDescription_Dev& desc) | |
| 81 : Resource(resource), | |
| 82 webkit_event_(false, false), | |
| 83 font_forwarding_(NULL) { | |
| 84 TRACE_EVENT0("ppapi proxy", "Font::Font"); | |
| 85 StringVar* face = StringVar::FromPPVar(desc.face); | |
| 86 | |
| 87 PluginDispatcher* dispatcher = PluginDispatcher::GetForResource(this); | |
| 88 if (!dispatcher) | |
| 89 return; | |
| 90 WebKitForwarding* forwarding = | |
| 91 PluginGlobals::Get()->plugin_proxy_delegate()->GetWebKitForwarding(); | |
| 92 | |
| 93 RunOnWebKitThread(true, | |
| 94 base::Bind(&WebKitForwarding::CreateFontForwarding, | |
| 95 base::Unretained(forwarding), | |
| 96 &webkit_event_, desc, | |
| 97 face ? face->value() : std::string(), | |
| 98 dispatcher->preferences(), | |
| 99 &font_forwarding_)); | |
| 100 } | |
| 101 | |
| 102 Font::~Font() { | |
| 103 if (font_forwarding_) { | |
| 104 RunOnWebKitThread(false, | |
| 105 base::Bind(&DeleteFontForwarding, font_forwarding_)); | |
| 106 } | |
| 107 } | |
| 108 | |
| 109 PPB_Font_API* Font::AsPPB_Font_API() { | |
| 110 return this; | |
| 111 } | |
| 112 | |
| 113 PP_Bool Font::Describe(PP_FontDescription_Dev* description, | |
| 114 PP_FontMetrics_Dev* metrics) { | |
| 115 TRACE_EVENT0("ppapi proxy", "Font::Describe"); | |
| 116 std::string face; | |
| 117 PP_Bool result = PP_FALSE; | |
| 118 if (font_forwarding_) { | |
| 119 RunOnWebKitThread(true, | |
| 120 base::Bind(&WebKitForwarding::Font::Describe, | |
| 121 base::Unretained(font_forwarding_), | |
| 122 &webkit_event_, description, &face, metrics, | |
| 123 &result)); | |
| 124 } | |
| 125 | |
| 126 if (PP_ToBool(result)) | |
| 127 description->face = StringVar::StringToPPVar(face); | |
| 128 else | |
| 129 description->face = PP_MakeUndefined(); | |
| 130 return result; | |
| 131 } | |
| 132 | |
| 133 PP_Bool Font::DrawTextAt(PP_Resource pp_image_data, | |
| 134 const PP_TextRun_Dev* text, | |
| 135 const PP_Point* position, | |
| 136 uint32_t color, | |
| 137 const PP_Rect* clip, | |
| 138 PP_Bool image_data_is_opaque) { | |
| 139 TRACE_EVENT0("ppapi proxy", "Font::DrawTextAt"); | |
| 140 if (!font_forwarding_) | |
| 141 return PP_FALSE; | |
| 142 | |
| 143 // Convert to an ImageData object. | |
| 144 EnterResourceNoLock<PPB_ImageData_API> enter(pp_image_data, true); | |
| 145 if (enter.failed()) | |
| 146 return PP_FALSE; | |
| 147 ImageData* image_data = static_cast<ImageData*>(enter.object()); | |
| 148 | |
| 149 skia::PlatformCanvas* canvas = image_data->mapped_canvas(); | |
| 150 bool needs_unmapping = false; | |
| 151 if (!canvas) { | |
| 152 needs_unmapping = true; | |
| 153 image_data->Map(); | |
| 154 canvas = image_data->mapped_canvas(); | |
| 155 if (!canvas) | |
| 156 return PP_FALSE; // Failure mapping. | |
| 157 } | |
| 158 | |
| 159 WebKitForwarding::Font::TextRun run; | |
| 160 if (!PPTextRunToTextRun(text, &run)) { | |
| 161 if (needs_unmapping) | |
| 162 image_data->Unmap(); | |
| 163 return PP_FALSE; | |
| 164 } | |
| 165 RunOnWebKitThread( | |
| 166 true, | |
| 167 base::Bind(&WebKitForwarding::Font::DrawTextAt, | |
| 168 base::Unretained(font_forwarding_), &webkit_event_, | |
| 169 WebKitForwarding::Font::DrawTextParams(canvas, run, position, | |
| 170 color, clip, | |
| 171 image_data_is_opaque))); | |
| 172 | |
| 173 if (needs_unmapping) | |
| 174 image_data->Unmap(); | |
| 175 return PP_TRUE; | |
| 176 } | |
| 177 | |
| 178 int32_t Font::MeasureText(const PP_TextRun_Dev* text) { | |
| 179 TRACE_EVENT0("ppapi proxy", "Font::MeasureText"); | |
| 180 WebKitForwarding::Font::TextRun run; | |
| 181 if (!font_forwarding_ || !PPTextRunToTextRun(text, &run)) | |
| 182 return -1; | |
| 183 int32_t result = -1; | |
| 184 RunOnWebKitThread(true, | |
| 185 base::Bind(&WebKitForwarding::Font::MeasureText, | |
| 186 base::Unretained(font_forwarding_), | |
| 187 &webkit_event_, run, &result)); | |
| 188 return result; | |
| 189 } | |
| 190 | |
| 191 uint32_t Font::CharacterOffsetForPixel(const PP_TextRun_Dev* text, | |
| 192 int32_t pixel_position) { | |
| 193 TRACE_EVENT0("ppapi proxy", "Font::CharacterOffsetForPixel"); | |
| 194 WebKitForwarding::Font::TextRun run; | |
| 195 if (!font_forwarding_ || !PPTextRunToTextRun(text, &run)) | |
| 196 return -1; | |
| 197 uint32_t result = -1; | |
| 198 RunOnWebKitThread(true, | |
| 199 base::Bind(&WebKitForwarding::Font::CharacterOffsetForPixel, | |
| 200 base::Unretained(font_forwarding_), | |
| 201 &webkit_event_, run, pixel_position, &result)); | |
| 202 return result; | |
| 203 } | |
| 204 | |
| 205 int32_t Font::PixelOffsetForCharacter(const PP_TextRun_Dev* text, | |
| 206 uint32_t char_offset) { | |
| 207 TRACE_EVENT0("ppapi proxy", "Font::PixelOffsetForCharacter"); | |
| 208 WebKitForwarding::Font::TextRun run; | |
| 209 if (!font_forwarding_ || !PPTextRunToTextRun(text, &run)) | |
| 210 return -1; | |
| 211 int32_t result = -1; | |
| 212 RunOnWebKitThread(true, | |
| 213 base::Bind(&WebKitForwarding::Font::PixelOffsetForCharacter, | |
| 214 base::Unretained(font_forwarding_), | |
| 215 &webkit_event_, run, char_offset, &result)); | |
| 216 return result; | |
| 217 } | |
| 218 | |
| 219 void Font::RunOnWebKitThread(bool blocking, const base::Closure& task) { | |
| 220 PluginGlobals::Get()->plugin_proxy_delegate()->PostToWebKitThread( | |
| 221 FROM_HERE, task); | |
| 222 if (blocking) | |
| 223 webkit_event_.Wait(); | |
| 224 } | |
| 225 | |
| 226 // static | |
| 227 void Font::DeleteFontForwarding(WebKitForwarding::Font* font_forwarding) { | |
| 228 delete font_forwarding; | |
| 229 } | |
| 230 | |
| 231 } // namespace proxy | 53 } // namespace proxy |
| 232 } // namespace ppapi | 54 } // namespace ppapi |
| OLD | NEW |