1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ppapi/cpp/trusted/browser_font_trusted.h"
6
7#include <algorithm>
8
9#include "ppapi/c/dev/ppb_font_dev.h"
10#include "ppapi/cpp/image_data.h"
11#include "ppapi/cpp/instance_handle.h"
12#include "ppapi/cpp/point.h"
13#include "ppapi/cpp/rect.h"
14#include "ppapi/cpp/module_impl.h"
15
16namespace pp {
17
18namespace {
19
20template <> const char* interface_name<PPB_BrowserFont_Trusted_1_0>() {
21  return PPB_BROWSERFONT_TRUSTED_INTERFACE_1_0;
22}
23template <> const char* interface_name<PPB_Font_Dev_0_6>() {
24  return PPB_FONT_DEV_INTERFACE_0_6;
25}
26
27// This class provides backwards compat for PPB_Font, which is binary
28// compatible with the BrowserFont interface.
29// TODO(brettw) remove PPB_Font altogether when Flash is updated.
30const PP_FontDescription_Dev* BrowserFontDescToFontDesc(
31    const PP_BrowserFont_Trusted_Description* desc) {
32  return reinterpret_cast<const PP_FontDescription_Dev*>(desc);
33}
34PP_FontDescription_Dev* BrowserFontDescToFontDesc(
35    PP_BrowserFont_Trusted_Description* desc) {
36  return reinterpret_cast<PP_FontDescription_Dev*>(desc);
37}
38PP_FontMetrics_Dev* BrowserFontMetricsToFontMetrics(
39    PP_BrowserFont_Trusted_Metrics* metrics) {
40  return reinterpret_cast<PP_FontMetrics_Dev*>(metrics);
41}
42const PP_TextRun_Dev* BrowserFontTextRunToFontTextRun(
43    const PP_BrowserFont_Trusted_TextRun* run) {
44  return reinterpret_cast<const PP_TextRun_Dev*>(run);
45}
46
47}  // namespace
48
49// BrowserFontDescription ------------------------------------------------------
50
51BrowserFontDescription::BrowserFontDescription() {
52  pp_font_description_.face = face_.pp_var();
53  set_family(PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT);
54  set_size(0);
55  set_weight(PP_BROWSERFONT_TRUSTED_WEIGHT_NORMAL);
56  set_italic(false);
57  set_small_caps(false);
58  set_letter_spacing(0);
59  set_word_spacing(0);
60}
61
62BrowserFontDescription::BrowserFontDescription(
63    const BrowserFontDescription& other) {
64  set_face(other.face());
65  set_family(other.family());
66  set_size(other.size());
67  set_weight(other.weight());
68  set_italic(other.italic());
69  set_small_caps(other.small_caps());
70  set_letter_spacing(other.letter_spacing());
71  set_word_spacing(other.word_spacing());
72}
73
74BrowserFontDescription::~BrowserFontDescription() {
75}
76
77BrowserFontDescription& BrowserFontDescription::operator=(
78    const BrowserFontDescription& other) {
79  pp_font_description_ = other.pp_font_description_;
80
81  // Be careful about the refcount of the string, the copy that operator= made
82  // above didn't copy a ref.
83  pp_font_description_.face = PP_MakeUndefined();
84  set_face(other.face());
85
86  return *this;
87}
88
89// BrowserFontTextRun ----------------------------------------------------------
90
91BrowserFontTextRun::BrowserFontTextRun() {
92  pp_text_run_.text = text_.pp_var();
93  pp_text_run_.rtl = PP_FALSE;
94  pp_text_run_.override_direction = PP_FALSE;
95}
96
97BrowserFontTextRun::BrowserFontTextRun(const std::string& text,
98                                       bool rtl,
99                                       bool override_direction)
100    : text_(text) {
101  pp_text_run_.text = text_.pp_var();
102  pp_text_run_.rtl = PP_FromBool(rtl);
103  pp_text_run_.override_direction = PP_FromBool(override_direction);
104}
105
106BrowserFontTextRun::BrowserFontTextRun(const BrowserFontTextRun& other)
107    : text_(other.text_) {
108  pp_text_run_.text = text_.pp_var();
109  pp_text_run_.rtl = other.pp_text_run_.rtl;
110  pp_text_run_.override_direction = other.pp_text_run_.override_direction;
111}
112
113BrowserFontTextRun::~BrowserFontTextRun() {
114}
115
116BrowserFontTextRun& BrowserFontTextRun::operator=(
117    const BrowserFontTextRun& other) {
118  pp_text_run_ = other.pp_text_run_;
119  text_ = other.text_;
120  pp_text_run_.text = text_.pp_var();
121  return *this;
122}
123
124// BrowserFont_Trusted ---------------------------------------------------------
125
126BrowserFont_Trusted::BrowserFont_Trusted() : Resource() {
127}
128
129BrowserFont_Trusted::BrowserFont_Trusted(PP_Resource resource)
130    : Resource(resource) {
131}
132
133BrowserFont_Trusted::BrowserFont_Trusted(
134    const InstanceHandle& instance,
135    const BrowserFontDescription& description) {
136  if (has_interface<PPB_BrowserFont_Trusted_1_0>()) {
137    PassRefFromConstructor(get_interface<PPB_BrowserFont_Trusted_1_0>()->Create(
138        instance.pp_instance(),
139        &description.pp_font_description()));
140  } else if (!has_interface<PPB_Font_Dev_0_6>()) {
141    PassRefFromConstructor(get_interface<PPB_Font_Dev_0_6>()->Create(
142        instance.pp_instance(),
143        BrowserFontDescToFontDesc(&description.pp_font_description())));
144  }
145}
146
147BrowserFont_Trusted::BrowserFont_Trusted(const BrowserFont_Trusted& other)
148    : Resource(other) {
149}
150
151BrowserFont_Trusted& BrowserFont_Trusted::operator=(
152    const BrowserFont_Trusted& other) {
153  Resource::operator=(other);
154  return *this;
155}
156
157// static
158Var BrowserFont_Trusted::GetFontFamilies(const InstanceHandle& instance) {
159  if (!has_interface<PPB_Font_Dev_0_6>())
160    return Var();
161  return Var(PASS_REF,
162             get_interface<PPB_Font_Dev_0_6>()->GetFontFamilies(
163                 instance.pp_instance()));
164}
165
166bool BrowserFont_Trusted::Describe(
167    BrowserFontDescription* description,
168    PP_BrowserFont_Trusted_Metrics* metrics) const {
169  // Be careful with ownership of the |face| string. It will come back with
170  // a ref of 1, which we want to assign to the |face_| member of the C++ class.
171  if (has_interface<PPB_BrowserFont_Trusted_1_0>()) {
172    if (!get_interface<PPB_BrowserFont_Trusted_1_0>()->Describe(
173        pp_resource(), &description->pp_font_description_, metrics))
174      return false;
175  } else if (!has_interface<PPB_Font_Dev_0_6>()) {
176    if (!get_interface<PPB_Font_Dev_0_6>()->Describe(
177        pp_resource(),
178        BrowserFontDescToFontDesc(&description->pp_font_description_),
179        BrowserFontMetricsToFontMetrics(metrics)))
180      return false;
181  }
182  description->face_ = Var(PASS_REF,
183                           description->pp_font_description_.face);
184  return true;
185}
186
187bool BrowserFont_Trusted::DrawTextAt(ImageData* dest,
188                                     const BrowserFontTextRun& text,
189                                     const Point& position,
190                                     uint32_t color,
191                                     const Rect& clip,
192                                     bool image_data_is_opaque) const {
193  if (has_interface<PPB_BrowserFont_Trusted_1_0>()) {
194    return PP_ToBool(get_interface<PPB_BrowserFont_Trusted_1_0>()->DrawTextAt(
195        pp_resource(),
196        dest->pp_resource(),
197        &text.pp_text_run(),
198        &position.pp_point(),
199        color,
200        &clip.pp_rect(),
201        PP_FromBool(image_data_is_opaque)));
202  } else if (!has_interface<PPB_Font_Dev_0_6>()) {
203    return PP_ToBool(get_interface<PPB_Font_Dev_0_6>()->DrawTextAt(
204        pp_resource(),
205        dest->pp_resource(),
206        BrowserFontTextRunToFontTextRun(&text.pp_text_run()),
207        &position.pp_point(),
208        color,
209        &clip.pp_rect(),
210        PP_FromBool(image_data_is_opaque)));
211  }
212  return false;
213}
214
215int32_t BrowserFont_Trusted::MeasureText(const BrowserFontTextRun& text) const {
216  if (has_interface<PPB_BrowserFont_Trusted_1_0>()) {
217    return get_interface<PPB_BrowserFont_Trusted_1_0>()->MeasureText(
218        pp_resource(),
219        &text.pp_text_run());
220  } else if (!has_interface<PPB_Font_Dev_0_6>()) {
221    return get_interface<PPB_Font_Dev_0_6>()->MeasureText(
222        pp_resource(),
223        BrowserFontTextRunToFontTextRun(&text.pp_text_run()));
224  }
225  return -1;
226}
227
228uint32_t BrowserFont_Trusted::CharacterOffsetForPixel(
229    const BrowserFontTextRun& text,
230    int32_t pixel_position) const {
231  if (has_interface<PPB_BrowserFont_Trusted_1_0>()) {
232    return get_interface<PPB_BrowserFont_Trusted_1_0>()->
233        CharacterOffsetForPixel(
234            pp_resource(),
235            &text.pp_text_run(),
236            pixel_position);
237  } else if (!has_interface<PPB_Font_Dev_0_6>()) {
238    return get_interface<PPB_Font_Dev_0_6>()->CharacterOffsetForPixel(
239        pp_resource(),
240        BrowserFontTextRunToFontTextRun(&text.pp_text_run()),
241        pixel_position);
242  }
243  return 0;
244}
245
246int32_t BrowserFont_Trusted::PixelOffsetForCharacter(
247    const BrowserFontTextRun& text,
248    uint32_t char_offset) const {
249  if (has_interface<PPB_BrowserFont_Trusted_1_0>()) {
250    return get_interface<PPB_BrowserFont_Trusted_1_0>()->
251        PixelOffsetForCharacter(
252           pp_resource(),
253           &text.pp_text_run(),
254           char_offset);
255  } else if (!has_interface<PPB_Font_Dev_0_6>()) {
256    return get_interface<PPB_Font_Dev_0_6>()->PixelOffsetForCharacter(
257        pp_resource(),
258        BrowserFontTextRunToFontTextRun(&text.pp_text_run()),
259        char_offset);
260  }
261  return 0;
262}
263
264bool BrowserFont_Trusted::DrawSimpleText(
265    ImageData* dest,
266    const std::string& text,
267    const Point& position,
268    uint32_t color,
269    bool image_data_is_opaque) const {
270  return DrawTextAt(dest, BrowserFontTextRun(text), position, color,
271                    Rect(dest->size()), image_data_is_opaque);
272}
273
274int32_t BrowserFont_Trusted::MeasureSimpleText(const std::string& text) const {
275  return MeasureText(BrowserFontTextRun(text));
276}
277
278}  // namespace pp
279