summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy/ppb_font_proxy.cc
blob: 9a4dbf5670fc54954ad12792d3b7f501d7021527 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
// Copyright (c) 2010 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/proxy/ppb_font_proxy.h"

#include "ppapi/c/dev/ppb_font_dev.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_resource.h"
#include "ppapi/proxy/ppapi_messages.h"

namespace pp {
namespace proxy {

class Font : public PluginResource {
 public:
  Font();
  virtual ~Font();

  // PluginResource overrides.
  virtual Font* AsFont() { return this; }

  PP_FontDescription_Dev& desc() { return desc_; }
  PP_FontDescription_Dev* desc_ptr() { return &desc_; }
  PP_FontMetrics_Dev& metrics() { return metrics_; }

 private:
  PP_FontDescription_Dev desc_;
  PP_FontMetrics_Dev metrics_;

  DISALLOW_COPY_AND_ASSIGN(Font);
};

Font::Font() {
  memset(&desc_, 0, sizeof(PP_FontDescription_Dev));
  desc_.face.type = PP_VARTYPE_UNDEFINED;
  memset(&metrics_, 0, sizeof(PP_FontMetrics_Dev));
}

Font::~Font() {
  PluginDispatcher::Get()->plugin_var_tracker()->Release(desc_.face);
}

namespace {

PP_Resource Create(PP_Module module_id,
                   const PP_FontDescription_Dev* description) {
  PluginDispatcher* dispatcher = PluginDispatcher::Get();

  SerializedFontDescription in_description;
  in_description.SetFromPPFontDescription(dispatcher, *description, true);

  PP_Resource result;
  SerializedFontDescription out_description;
  std::string out_metrics;
  PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBFont_Create(
      INTERFACE_ID_PPB_FONT,
      module_id, in_description, &result, &out_description, &out_metrics));

  if (!result)
    return 0;  // Failure creating font.

  linked_ptr<Font> object(new Font);
  out_description.SetToPPFontDescription(dispatcher, object->desc_ptr(), true);

  // Convert the metrics, this is just serialized as a string of bytes.
  if (out_metrics.size() != sizeof(PP_FontMetrics_Dev))
    return 0;
  memcpy(&object->metrics(), out_metrics.data(), sizeof(PP_FontMetrics_Dev));

  dispatcher->plugin_resource_tracker()->AddResource(result, object);
  return result;
}

PP_Bool IsFont(PP_Resource resource) {
  Font* object = PluginResource::GetAs<Font>(resource);
  return BoolToPPBool(!!object);
}

PP_Bool Describe(PP_Resource font_id,
              PP_FontDescription_Dev* description,
              PP_FontMetrics_Dev* metrics) {
  Font* object = PluginResource::GetAs<Font>(font_id);
  if (!object)
    return PP_FALSE;

  // Copy the description, the caller expects its face PP_Var to have a ref
  // added to it on its behalf.
  memcpy(description, &object->desc(), sizeof(PP_FontDescription_Dev));
  PluginDispatcher::Get()->plugin_var_tracker()->AddRef(description->face);

  memcpy(metrics, &object->metrics(), sizeof(PP_FontMetrics_Dev));
  return PP_TRUE;
}

PP_Bool DrawTextAt(PP_Resource font_id,
                   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) {
  PPBFont_DrawTextAt_Params params;
  params.font = font_id;
  params.image_data = image_data;
  params.text_is_rtl = text->rtl;
  params.override_direction = text->override_direction;
  params.position = *position;
  params.color = color;
  if (clip) {
    params.clip = *clip;
    params.clip_is_null = false;
  } else {
    params.clip = PP_MakeRectFromXYWH(0, 0, 0, 0);
    params.clip_is_null = true;
  }
  params.image_data_is_opaque = image_data_is_opaque;

  Dispatcher* dispatcher = PluginDispatcher::Get();
  PP_Bool result = PP_FALSE;
  dispatcher->Send(new PpapiHostMsg_PPBFont_DrawTextAt(
      INTERFACE_ID_PPB_FONT,
      SerializedVarSendInput(dispatcher, text->text),
      params, &result));
  return result;
}

int32_t MeasureText(PP_Resource font_id, const PP_TextRun_Dev* text) {
  Dispatcher* dispatcher = PluginDispatcher::Get();
  int32_t result = 0;
  dispatcher->Send(new PpapiHostMsg_PPBFont_MeasureText(
      INTERFACE_ID_PPB_FONT, font_id,
      SerializedVarSendInput(dispatcher, text->text),
      text->rtl, text->override_direction, &result));
  return result;
}

uint32_t CharacterOffsetForPixel(PP_Resource font_id,
                                 const PP_TextRun_Dev* text,
                                 int32_t pixel_position) {
  Dispatcher* dispatcher = PluginDispatcher::Get();
  uint32_t result = 0;
  dispatcher->Send(new PpapiHostMsg_PPBFont_CharacterOffsetForPixel(
      INTERFACE_ID_PPB_FONT, font_id,
      SerializedVarSendInput(dispatcher, text->text),
      text->rtl, text->override_direction, pixel_position, &result));
  return result;
}

int32_t PixelOffsetForCharacter(PP_Resource font_id,
                                const PP_TextRun_Dev* text,
                                uint32_t char_offset) {
  Dispatcher* dispatcher = PluginDispatcher::Get();
  int32_t result = 0;
  dispatcher->Send(new PpapiHostMsg_PPBFont_PixelOffsetForCharacter(
      INTERFACE_ID_PPB_FONT, font_id,
      SerializedVarSendInput(dispatcher, text->text),
      text->rtl, text->override_direction, char_offset, &result));
  return result;
}

const PPB_Font_Dev ppb_font_interface = {
  &Create,
  &IsFont,
  &Describe,
  &DrawTextAt,
  &MeasureText,
  &CharacterOffsetForPixel,
  &PixelOffsetForCharacter
};

}  // namespace

PPB_Font_Proxy::PPB_Font_Proxy(Dispatcher* dispatcher,
                               const void* target_interface)
    : InterfaceProxy(dispatcher, target_interface) {
}

PPB_Font_Proxy::~PPB_Font_Proxy() {
}

const void* PPB_Font_Proxy::GetSourceInterface() const {
  return &ppb_font_interface;
}

InterfaceID PPB_Font_Proxy::GetInterfaceId() const {
  return INTERFACE_ID_PPB_FONT;
}

void PPB_Font_Proxy::OnMessageReceived(const IPC::Message& msg) {
  IPC_BEGIN_MESSAGE_MAP(PPB_Font_Proxy, msg)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_Create,
                        OnMsgCreate)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_DrawTextAt,
                        OnMsgDrawTextAt)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_MeasureText,
                        OnMsgMeasureText)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_CharacterOffsetForPixel,
                        OnMsgCharacterOffsetForPixel)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_PixelOffsetForCharacter,
                        OnMsgPixelOffsetForCharacter)
  IPC_END_MESSAGE_MAP()
}

void PPB_Font_Proxy::OnMsgCreate(
    PP_Module pp_module,
    const SerializedFontDescription& in_description,
    PP_Resource* result,
    SerializedFontDescription* out_description,
    std::string* out_metrics) {
  // Convert the face name in the input description.
  PP_FontDescription_Dev in_pp_desc;
  in_description.SetToPPFontDescription(dispatcher(), &in_pp_desc, false);

  // Make sure the output is always defined so we can still serialize it back
  // to the plugin below.
  PP_FontDescription_Dev out_pp_desc;
  memset(&out_pp_desc, 0, sizeof(PP_FontDescription_Dev));
  out_pp_desc.face = PP_MakeUndefined();

  *result = ppb_font_target()->Create(pp_module, &in_pp_desc);
  if (*result) {
    // Get the metrics and resulting description to return to the browser.
    PP_FontMetrics_Dev metrics;
    if (ppb_font_target()->Describe(*result, &out_pp_desc, &metrics)) {
        out_metrics->assign(reinterpret_cast<const char*>(&metrics),
                            sizeof(PP_FontMetrics_Dev));
    }
  }

  // This must always get called or it will assert when trying to serialize
  // the un-filled-in SerializedFontDescription as the return value.
  out_description->SetFromPPFontDescription(dispatcher(), out_pp_desc, false);
}

void PPB_Font_Proxy::OnMsgDrawTextAt(SerializedVarReceiveInput text,
                                     const PPBFont_DrawTextAt_Params& params,
                                     PP_Bool* result) {
  PP_TextRun_Dev run;
  run.text = text.Get(dispatcher());
  run.rtl = params.text_is_rtl;
  run.override_direction = params.override_direction;

  *result = ppb_font_target()->DrawTextAt(params.font, params.image_data,
      &run, &params.position, params.color,
      params.clip_is_null ? NULL : &params.clip, params.image_data_is_opaque);
}

void PPB_Font_Proxy::OnMsgMeasureText(PP_Resource font,
                                      SerializedVarReceiveInput text,
                                      PP_Bool text_is_rtl,
                                      PP_Bool override_direction,
                                      int32_t* result) {
  PP_TextRun_Dev run;
  run.text = text.Get(dispatcher());
  run.rtl = text_is_rtl;
  run.override_direction = override_direction;

  *result = ppb_font_target()->MeasureText(font, &run);
}

void PPB_Font_Proxy::OnMsgCharacterOffsetForPixel(
    PP_Resource font,
    SerializedVarReceiveInput text,
    PP_Bool text_is_rtl,
    PP_Bool override_direction,
    int32_t pixel_pos,
    uint32_t* result) {
  PP_TextRun_Dev run;
  run.text = text.Get(dispatcher());
  run.rtl = text_is_rtl;
  run.override_direction = override_direction;

  *result = ppb_font_target()->CharacterOffsetForPixel(font, &run, pixel_pos);
}

void PPB_Font_Proxy::OnMsgPixelOffsetForCharacter(
    PP_Resource font,
    SerializedVarReceiveInput text,
    PP_Bool text_is_rtl,
    PP_Bool override_direction,
    uint32_t char_offset,
    int32_t* result) {
  PP_TextRun_Dev run;
  run.text = text.Get(dispatcher());
  run.rtl = text_is_rtl;
  run.override_direction = override_direction;

  *result = ppb_font_target()->PixelOffsetForCharacter(font, &run, char_offset);
}

}  // namespace proxy
}  // namespace pp