Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Side by Side Diff: ppapi/proxy/ppb_font_proxy.cc

Issue 6981001: Make the Pepper proxy support in-process font rendering. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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, &params.position, params.color,
292 params.clip_is_null ? NULL : &params.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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698