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" | |
7 #include "ppapi/c/dev/ppb_font_dev.h" | 8 #include "ppapi/c/dev/ppb_font_dev.h" |
8 #include "ppapi/proxy/plugin_dispatcher.h" | 9 #include "ppapi/proxy/plugin_dispatcher.h" |
9 #include "ppapi/proxy/plugin_resource.h" | |
10 #include "ppapi/proxy/ppapi_messages.h" | 10 #include "ppapi/proxy/ppapi_messages.h" |
11 #include "ppapi/proxy/ppb_image_data_proxy.h" | |
12 #include "ppapi/shared_impl/resource_object_base.h" | |
13 #include "ppapi/thunk/ppb_image_data_api.h" | |
14 #include "ppapi/thunk/thunk.h" | |
15 | |
16 using ppapi::thunk::PPB_ImageData_API; | |
11 | 17 |
12 namespace pp { | 18 namespace pp { |
13 namespace proxy { | 19 namespace proxy { |
14 | 20 |
15 class Font : public PluginResource { | |
16 public: | |
17 Font(const HostResource& resource); | |
18 virtual ~Font(); | |
19 | |
20 // PluginResource overrides. | |
21 virtual Font* AsFont() { return this; } | |
22 | |
23 PP_FontDescription_Dev& desc() { return desc_; } | |
24 PP_FontDescription_Dev* desc_ptr() { return &desc_; } | |
25 PP_FontMetrics_Dev& metrics() { return metrics_; } | |
26 | |
27 private: | |
28 PP_FontDescription_Dev desc_; | |
29 PP_FontMetrics_Dev metrics_; | |
30 | |
31 DISALLOW_COPY_AND_ASSIGN(Font); | |
32 }; | |
33 | |
34 Font::Font(const HostResource& resource) : PluginResource(resource) { | |
35 memset(&desc_, 0, sizeof(PP_FontDescription_Dev)); | |
36 desc_.face.type = PP_VARTYPE_UNDEFINED; | |
37 memset(&metrics_, 0, sizeof(PP_FontMetrics_Dev)); | |
38 } | |
39 | |
40 Font::~Font() { | |
41 PluginVarTracker::GetInstance()->Release(desc_.face); | |
42 } | |
43 | |
44 namespace { | 21 namespace { |
45 | 22 |
46 PP_Resource Create(PP_Instance instance, | 23 bool PPTextRunToTextRun(const PP_TextRun_Dev* run, |
47 const PP_FontDescription_Dev* description) { | 24 Font::TextRun* output) { |
48 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); | 25 const std::string* str = PluginVarTracker::GetInstance()->GetExistingString( |
49 if (!dispatcher) | 26 run->text); |
50 return 0; | 27 if (!str) |
28 return false; | |
51 | 29 |
52 SerializedFontDescription in_description; | 30 output->text = *str; |
53 in_description.SetFromPPFontDescription(dispatcher, *description, true); | 31 output->rtl = PPBoolToBool(run->rtl); |
54 | 32 output->override_direction = PPBoolToBool(run->override_direction); |
55 HostResource result; | 33 return true; |
56 SerializedFontDescription out_description; | |
57 std::string out_metrics; | |
58 dispatcher->Send(new PpapiHostMsg_PPBFont_Create( | |
59 INTERFACE_ID_PPB_FONT, | |
60 instance, in_description, &result, &out_description, &out_metrics)); | |
61 | |
62 if (result.is_null()) | |
63 return 0; // Failure creating font. | |
64 | |
65 linked_ptr<Font> object(new Font(result)); | |
66 out_description.SetToPPFontDescription(dispatcher, object->desc_ptr(), true); | |
67 | |
68 // Convert the metrics, this is just serialized as a string of bytes. | |
69 if (out_metrics.size() != sizeof(PP_FontMetrics_Dev)) | |
70 return 0; | |
71 memcpy(&object->metrics(), out_metrics.data(), sizeof(PP_FontMetrics_Dev)); | |
72 | |
73 return PluginResourceTracker::GetInstance()->AddResource(object); | |
74 } | 34 } |
75 | 35 |
76 PP_Bool IsFont(PP_Resource resource) { | |
77 Font* object = PluginResource::GetAs<Font>(resource); | |
78 return BoolToPPBool(!!object); | |
79 } | |
80 | |
81 PP_Bool Describe(PP_Resource font_id, | |
82 PP_FontDescription_Dev* description, | |
83 PP_FontMetrics_Dev* metrics) { | |
84 Font* object = PluginResource::GetAs<Font>(font_id); | |
85 if (!object) | |
86 return PP_FALSE; | |
87 | |
88 // Copy the description, the caller expects its face PP_Var to have a ref | |
89 // added to it on its behalf. | |
90 memcpy(description, &object->desc(), sizeof(PP_FontDescription_Dev)); | |
91 PluginVarTracker::GetInstance()->AddRef(description->face); | |
92 | |
93 memcpy(metrics, &object->metrics(), sizeof(PP_FontMetrics_Dev)); | |
94 return PP_TRUE; | |
95 } | |
96 | |
97 PP_Bool DrawTextAt(PP_Resource font_id, | |
98 PP_Resource image_data, | |
99 const PP_TextRun_Dev* text, | |
100 const PP_Point* position, | |
101 uint32_t color, | |
102 const PP_Rect* clip, | |
103 PP_Bool image_data_is_opaque) { | |
104 Font* font_object = PluginResource::GetAs<Font>(font_id); | |
105 if (!font_object) | |
106 return PP_FALSE; | |
107 PluginResource* image_object = PluginResourceTracker::GetInstance()-> | |
108 GetResourceObject(image_data); | |
109 if (!image_object) | |
110 return PP_FALSE; | |
111 if (font_object->instance() != image_object->instance()) | |
112 return PP_FALSE; | |
113 | |
114 PPBFont_DrawTextAt_Params params; | |
115 params.font = font_object->host_resource(); | |
116 params.image_data = image_object->host_resource(); | |
117 params.text_is_rtl = text->rtl; | |
118 params.override_direction = text->override_direction; | |
119 params.position = *position; | |
120 params.color = color; | |
121 if (clip) { | |
122 params.clip = *clip; | |
123 params.clip_is_null = false; | |
124 } else { | |
125 params.clip = PP_MakeRectFromXYWH(0, 0, 0, 0); | |
126 params.clip_is_null = true; | |
127 } | |
128 params.image_data_is_opaque = image_data_is_opaque; | |
129 | |
130 Dispatcher* dispatcher = PluginDispatcher::GetForInstance( | |
131 image_object->instance()); | |
132 PP_Bool result = PP_FALSE; | |
133 if (dispatcher) { | |
134 dispatcher->Send(new PpapiHostMsg_PPBFont_DrawTextAt( | |
135 INTERFACE_ID_PPB_FONT, | |
136 SerializedVarSendInput(dispatcher, text->text), | |
137 params, &result)); | |
138 } | |
139 return result; | |
140 } | |
141 | |
142 int32_t MeasureText(PP_Resource font_id, const PP_TextRun_Dev* text) { | |
143 Font* object = PluginResource::GetAs<Font>(font_id); | |
144 if (!object) | |
145 return -1; | |
146 | |
147 Dispatcher* dispatcher = PluginDispatcher::GetForInstance(object->instance()); | |
148 int32_t result = 0; | |
149 if (dispatcher) { | |
150 dispatcher->Send(new PpapiHostMsg_PPBFont_MeasureText( | |
151 INTERFACE_ID_PPB_FONT, object->host_resource(), | |
152 SerializedVarSendInput(dispatcher, text->text), | |
153 text->rtl, text->override_direction, &result)); | |
154 } | |
155 return result; | |
156 } | |
157 | |
158 uint32_t CharacterOffsetForPixel(PP_Resource font_id, | |
159 const PP_TextRun_Dev* text, | |
160 int32_t pixel_position) { | |
161 Font* object = PluginResource::GetAs<Font>(font_id); | |
162 if (!object) | |
163 return -1; | |
164 | |
165 Dispatcher* dispatcher = PluginDispatcher::GetForInstance(object->instance()); | |
166 uint32_t result = 0; | |
167 if (dispatcher) { | |
168 dispatcher->Send(new PpapiHostMsg_PPBFont_CharacterOffsetForPixel( | |
169 INTERFACE_ID_PPB_FONT, object->host_resource(), | |
170 SerializedVarSendInput(dispatcher, text->text), | |
171 text->rtl, text->override_direction, pixel_position, &result)); | |
172 } | |
173 return result; | |
174 } | |
175 | |
176 int32_t PixelOffsetForCharacter(PP_Resource font_id, | |
177 const PP_TextRun_Dev* text, | |
178 uint32_t char_offset) { | |
179 Font* object = PluginResource::GetAs<Font>(font_id); | |
180 if (!object) | |
181 return -1; | |
182 | |
183 Dispatcher* dispatcher = PluginDispatcher::GetForInstance(object->instance()); | |
184 int32_t result = 0; | |
185 if (dispatcher) { | |
186 dispatcher->Send(new PpapiHostMsg_PPBFont_PixelOffsetForCharacter( | |
187 INTERFACE_ID_PPB_FONT, object->host_resource(), | |
188 SerializedVarSendInput(dispatcher, text->text), | |
189 text->rtl, text->override_direction, char_offset, &result)); | |
190 } | |
191 return result; | |
192 } | |
193 | |
194 const PPB_Font_Dev font_interface = { | |
195 &Create, | |
196 &IsFont, | |
197 &Describe, | |
198 &DrawTextAt, | |
199 &MeasureText, | |
200 &CharacterOffsetForPixel, | |
201 &PixelOffsetForCharacter | |
202 }; | |
203 | |
204 InterfaceProxy* CreateFontProxy(Dispatcher* dispatcher, | 36 InterfaceProxy* CreateFontProxy(Dispatcher* dispatcher, |
205 const void* target_interface) { | 37 const void* target_interface) { |
206 return new PPB_Font_Proxy(dispatcher, target_interface); | 38 return new PPB_Font_Proxy(dispatcher, target_interface); |
207 } | 39 } |
208 | 40 |
209 } // namespace | 41 } // namespace |
210 | 42 |
211 PPB_Font_Proxy::PPB_Font_Proxy(Dispatcher* dispatcher, | 43 PPB_Font_Proxy::PPB_Font_Proxy(Dispatcher* dispatcher, |
212 const void* target_interface) | 44 const void* target_interface) |
213 : InterfaceProxy(dispatcher, target_interface) { | 45 : InterfaceProxy(dispatcher, target_interface) { |
214 } | 46 } |
215 | 47 |
216 PPB_Font_Proxy::~PPB_Font_Proxy() { | 48 PPB_Font_Proxy::~PPB_Font_Proxy() { |
217 } | 49 } |
218 | 50 |
219 // static | 51 // static |
220 const InterfaceProxy::Info* PPB_Font_Proxy::GetInfo() { | 52 const InterfaceProxy::Info* PPB_Font_Proxy::GetInfo() { |
221 static const Info info = { | 53 static const Info info = { |
222 &font_interface, | 54 ::ppapi::thunk::GetPPB_Font_Thunk(), |
223 PPB_FONT_DEV_INTERFACE, | 55 PPB_FONT_DEV_INTERFACE, |
224 INTERFACE_ID_PPB_FONT, | 56 INTERFACE_ID_PPB_FONT, |
225 false, | 57 false, |
226 &CreateFontProxy, | 58 &CreateFontProxy, |
227 }; | 59 }; |
228 return &info; | 60 return &info; |
229 } | 61 } |
230 | 62 |
231 bool PPB_Font_Proxy::OnMessageReceived(const IPC::Message& msg) { | 63 bool PPB_Font_Proxy::OnMessageReceived(const IPC::Message& msg) { |
232 bool handled = true; | 64 // There aren't any font messages. |
233 IPC_BEGIN_MESSAGE_MAP(PPB_Font_Proxy, msg) | 65 NOTREACHED(); |
234 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_Create, | 66 return false; |
235 OnMsgCreate) | |
236 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_DrawTextAt, | |
237 OnMsgDrawTextAt) | |
238 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_MeasureText, | |
239 OnMsgMeasureText) | |
240 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_CharacterOffsetForPixel, | |
241 OnMsgCharacterOffsetForPixel) | |
242 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_PixelOffsetForCharacter, | |
243 OnMsgPixelOffsetForCharacter) | |
244 IPC_MESSAGE_UNHANDLED(handled = false) | |
245 IPC_END_MESSAGE_MAP() | |
246 return handled; | |
247 } | 67 } |
248 | 68 |
249 void PPB_Font_Proxy::OnMsgCreate( | 69 Font::Font(const HostResource& resource, |
250 PP_Instance instance, | 70 const PP_FontDescription_Dev& desc) |
251 const SerializedFontDescription& in_description, | 71 : PluginResource(resource), |
252 HostResource* result, | 72 webkit_event_(false, false) { |
253 SerializedFontDescription* out_description, | 73 const std::string* face = PluginVarTracker::GetInstance()->GetExistingString( |
254 std::string* out_metrics) { | 74 desc.face); |
255 // Convert the face name in the input description. | 75 RunOnWebKitThread(base::Bind(&Font::DoCreate, base::Unretained(this), |
256 PP_FontDescription_Dev in_pp_desc; | 76 &webkit_event_, desc, |
257 in_description.SetToPPFontDescription(dispatcher(), &in_pp_desc, false); | 77 face ? *face : std::string())); |
78 } | |
258 | 79 |
259 // Make sure the output is always defined so we can still serialize it back | 80 Font::~Font() { |
260 // to the plugin below. | 81 } |
261 PP_FontDescription_Dev out_pp_desc; | |
262 memset(&out_pp_desc, 0, sizeof(PP_FontDescription_Dev)); | |
263 out_pp_desc.face = PP_MakeUndefined(); | |
264 | 82 |
265 result->SetHostResource(instance, | 83 ppapi::thunk::PPB_Font_API* Font::AsFont_API() { |
266 ppb_font_target()->Create(instance, &in_pp_desc)); | 84 return this; |
267 if (!result->is_null()) { | 85 } |
268 // Get the metrics and resulting description to return to the browser. | 86 |
269 PP_FontMetrics_Dev metrics; | 87 Font* Font::AsFont() { |
270 if (ppb_font_target()->Describe(result->host_resource(), &out_pp_desc, | 88 return this; |
271 &metrics)) { | 89 } |
272 out_metrics->assign(reinterpret_cast<const char*>(&metrics), | 90 |
273 sizeof(PP_FontMetrics_Dev)); | 91 PP_Bool Font::Describe(PP_FontDescription_Dev* description, |
274 } | 92 PP_FontMetrics_Dev* metrics) { |
93 std::string face; | |
94 PP_Bool result = PP_FALSE; | |
95 RunOnWebKitThread(base::Bind(&Font::DoDescribe, base::Unretained(this), | |
96 &webkit_event_, description, &face, metrics, | |
97 &result)); | |
98 | |
99 if (result == PP_TRUE) { | |
100 description->face.type = PP_VARTYPE_STRING; | |
101 description->face.value.as_id = | |
102 PluginVarTracker::GetInstance()->MakeString(face); | |
103 } else { | |
104 description->face.type = PP_VARTYPE_UNDEFINED; | |
105 } | |
106 return result; | |
107 } | |
108 | |
109 PP_Bool Font::DrawTextAt(PP_Resource pp_image_data, | |
110 const PP_TextRun_Dev* text, | |
111 const PP_Point* position, | |
112 uint32_t color, | |
113 const PP_Rect* clip, | |
114 PP_Bool image_data_is_opaque) { | |
115 // Convert to an ImageData object. | |
116 ppapi::shared_impl::ResourceObjectBase* image_base = | |
117 ppapi::shared_impl::TrackerBase::Get()->GetResourceAPI(pp_image_data); | |
118 if (!image_base) | |
119 return PP_FALSE; | |
120 PPB_ImageData_API* image_api = image_base->GetAs<PPB_ImageData_API>(); | |
121 if (!image_api) | |
122 return PP_FALSE; | |
123 ImageData* image_data = static_cast<ImageData*>(image_api); | |
124 | |
125 skia::PlatformCanvas* canvas = image_data->mapped_canvas(); | |
126 bool needs_unmapping = false; | |
127 if (!canvas) { | |
128 needs_unmapping = true; | |
129 image_data->Map(); | |
130 canvas = image_data->mapped_canvas(); | |
131 if (!canvas) | |
132 return PP_FALSE; // Failure mapping. | |
275 } | 133 } |
276 | 134 |
277 // This must always get called or it will assert when trying to serialize | 135 TextRun run; |
278 // the un-filled-in SerializedFontDescription as the return value. | 136 if (!PPTextRunToTextRun(text, &run)) |
279 out_description->SetFromPPFontDescription(dispatcher(), out_pp_desc, false); | 137 return PP_FALSE; |
piman
2011/05/09 20:13:44
also image_data->Unmap() here - I know it's a noop
| |
138 RunOnWebKitThread(base::Bind(&Font::DoDrawTextAt, base::Unretained(this), | |
139 &webkit_event_, | |
140 DrawTextParams(canvas, run, position, color, | |
141 clip, image_data_is_opaque))); | |
142 | |
143 if (needs_unmapping) | |
144 image_data->Unmap(); | |
145 return PP_TRUE; | |
280 } | 146 } |
281 | 147 |
282 void PPB_Font_Proxy::OnMsgDrawTextAt(SerializedVarReceiveInput text, | 148 int32_t Font::MeasureText(const PP_TextRun_Dev* text) { |
283 const PPBFont_DrawTextAt_Params& params, | 149 TextRun run; |
284 PP_Bool* result) { | 150 if (!PPTextRunToTextRun(text, &run)) |
285 PP_TextRun_Dev run; | 151 return -1; |
286 run.text = text.Get(dispatcher()); | 152 int32_t result = -1; |
287 run.rtl = params.text_is_rtl; | 153 RunOnWebKitThread(base::Bind(&Font::DoMeasureText, base::Unretained(this), |
288 run.override_direction = params.override_direction; | 154 &webkit_event_, run, &result)); |
289 | 155 return result; |
290 *result = ppb_font_target()->DrawTextAt(params.font.host_resource(), | |
291 params.image_data.host_resource(), &run, ¶ms.position, params.color, | |
292 params.clip_is_null ? NULL : ¶ms.clip, params.image_data_is_opaque); | |
293 } | 156 } |
294 | 157 |
295 void PPB_Font_Proxy::OnMsgMeasureText(HostResource font, | 158 uint32_t Font::CharacterOffsetForPixel(const PP_TextRun_Dev* text, |
296 SerializedVarReceiveInput text, | 159 int32_t pixel_position) { |
297 PP_Bool text_is_rtl, | 160 TextRun run; |
298 PP_Bool override_direction, | 161 if (!PPTextRunToTextRun(text, &run)) |
299 int32_t* result) { | 162 return -1; |
300 PP_TextRun_Dev run; | 163 uint32_t result = -1; |
301 run.text = text.Get(dispatcher()); | 164 RunOnWebKitThread(base::Bind(&Font::DoCharacterOffsetForPixel, |
302 run.rtl = text_is_rtl; | 165 base::Unretained(this), |
303 run.override_direction = override_direction; | 166 &webkit_event_, run, pixel_position, &result)); |
304 | 167 return result; |
305 *result = ppb_font_target()->MeasureText(font.host_resource(), &run); | |
306 } | 168 } |
307 | 169 |
308 void PPB_Font_Proxy::OnMsgCharacterOffsetForPixel( | 170 int32_t Font::PixelOffsetForCharacter(const PP_TextRun_Dev* text, |
309 HostResource font, | 171 uint32_t char_offset) { |
310 SerializedVarReceiveInput text, | 172 TextRun run; |
311 PP_Bool text_is_rtl, | 173 if (!PPTextRunToTextRun(text, &run)) |
312 PP_Bool override_direction, | 174 return -1; |
313 int32_t pixel_pos, | 175 int32_t result = -1; |
314 uint32_t* result) { | 176 RunOnWebKitThread(base::Bind(&Font::DoPixelOffsetForCharacter, |
315 PP_TextRun_Dev run; | 177 base::Unretained(this), |
316 run.text = text.Get(dispatcher()); | 178 &webkit_event_, run, char_offset, &result)); |
317 run.rtl = text_is_rtl; | 179 return result; |
318 run.override_direction = override_direction; | |
319 | |
320 *result = ppb_font_target()->CharacterOffsetForPixel(font.host_resource(), | |
321 &run, pixel_pos); | |
322 } | 180 } |
323 | 181 |
324 void PPB_Font_Proxy::OnMsgPixelOffsetForCharacter( | 182 void Font::RunOnWebKitThread(const base::Closure& task) { |
325 HostResource font, | 183 GetDispatcher()->PostToWebKitThread(FROM_HERE, task); |
326 SerializedVarReceiveInput text, | 184 webkit_event_.Wait(); |
327 PP_Bool text_is_rtl, | |
328 PP_Bool override_direction, | |
329 uint32_t char_offset, | |
330 int32_t* result) { | |
331 PP_TextRun_Dev run; | |
332 run.text = text.Get(dispatcher()); | |
333 run.rtl = text_is_rtl; | |
334 run.override_direction = override_direction; | |
335 | |
336 *result = ppb_font_target()->PixelOffsetForCharacter(font.host_resource(), | |
337 &run, char_offset); | |
338 } | 185 } |
339 | 186 |
340 } // namespace proxy | 187 } // namespace proxy |
341 } // namespace pp | 188 } // namespace pp |
OLD | NEW |