Upstream version 9.37.197.0
[platform/framework/web/crosswalk.git] / src / content / renderer / pepper / pepper_truetype_font_linux.cc
1 // Copyright (c) 2013 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 "base/compiler_specific.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/numerics/safe_conversions.h"
8 #include "base/sys_byteorder.h"
9 #include "content/public/common/child_process_sandbox_support_linux.h"
10 #include "content/renderer/pepper/pepper_truetype_font.h"
11 #include "ppapi/c/dev/ppb_truetype_font_dev.h"
12 #include "ppapi/c/pp_errors.h"
13 #include "ppapi/c/trusted/ppb_browser_font_trusted.h"
14
15 namespace content {
16
17 namespace {
18
19 class PepperTrueTypeFontLinux : public PepperTrueTypeFont {
20  public:
21   explicit PepperTrueTypeFontLinux(
22       const ppapi::proxy::SerializedTrueTypeFontDesc& desc);
23   virtual ~PepperTrueTypeFontLinux() OVERRIDE;
24
25   // PepperTrueTypeFont overrides.
26   virtual bool IsValid() OVERRIDE;
27   virtual int32_t Describe(ppapi::proxy::SerializedTrueTypeFontDesc* desc)
28       OVERRIDE;
29   virtual int32_t GetTableTags(std::vector<uint32_t>* tags) OVERRIDE;
30   virtual int32_t GetTable(uint32_t table_tag,
31                            int32_t offset,
32                            int32_t max_data_length,
33                            std::string* data) OVERRIDE;
34
35  private:
36   // Save creation parameters here and use these to implement Describe.
37   // TODO(bbudge) Modify content API to return results of font matching and
38   // fallback.
39   ppapi::proxy::SerializedTrueTypeFontDesc desc_;
40   int fd_;
41
42   DISALLOW_COPY_AND_ASSIGN(PepperTrueTypeFontLinux);
43 };
44
45 PepperTrueTypeFontLinux::PepperTrueTypeFontLinux(
46     const ppapi::proxy::SerializedTrueTypeFontDesc& desc)
47     : desc_(desc) {
48   // If no face is provided, convert family to the platform defaults. These
49   // names should be mapped by FontConfig to an appropriate default font.
50   if (desc_.family.empty()) {
51     switch (desc_.generic_family) {
52       case PP_TRUETYPEFONTFAMILY_SERIF:
53         desc_.family = "serif";
54         break;
55       case PP_TRUETYPEFONTFAMILY_SANSSERIF:
56         desc_.family = "sans-serif";
57         break;
58       case PP_TRUETYPEFONTFAMILY_CURSIVE:
59         desc_.family = "cursive";
60         break;
61       case PP_TRUETYPEFONTFAMILY_FANTASY:
62         desc_.family = "fantasy";
63         break;
64       case PP_TRUETYPEFONTFAMILY_MONOSPACE:
65         desc_.family = "monospace";
66         break;
67     }
68   }
69
70   fd_ = MatchFontWithFallback(desc_.family.c_str(),
71                               desc_.weight >= PP_TRUETYPEFONTWEIGHT_BOLD,
72                               desc_.style & PP_TRUETYPEFONTSTYLE_ITALIC,
73                               desc_.charset,
74                               PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT);
75 }
76
77 PepperTrueTypeFontLinux::~PepperTrueTypeFontLinux() {}
78
79 bool PepperTrueTypeFontLinux::IsValid() { return fd_ != -1; }
80
81 int32_t PepperTrueTypeFontLinux::Describe(
82     ppapi::proxy::SerializedTrueTypeFontDesc* desc) {
83   *desc = desc_;
84   return PP_OK;
85 }
86
87 int32_t PepperTrueTypeFontLinux::GetTableTags(std::vector<uint32_t>* tags) {
88   // Get the 2 byte numTables field at an offset of 4 in the font.
89   uint8_t num_tables_buf[2];
90   size_t output_length = sizeof(num_tables_buf);
91   if (!GetFontTable(fd_,
92                     0 /* tag */,
93                     4 /* offset */,
94                     reinterpret_cast<uint8_t*>(&num_tables_buf),
95                     &output_length))
96     return PP_ERROR_FAILED;
97   DCHECK(output_length == sizeof(num_tables_buf));
98   // Font data is stored in big-endian order.
99   uint16_t num_tables = (num_tables_buf[0] << 8) | num_tables_buf[1];
100
101   // The font has a header, followed by n table entries in its directory.
102   static const size_t kFontHeaderSize = 12;
103   static const size_t kTableEntrySize = 16;
104   output_length = num_tables * kTableEntrySize;
105   scoped_ptr<uint8_t[]> table_entries(new uint8_t[output_length]);
106   // Get the table directory entries, which follow the font header.
107   if (!GetFontTable(fd_,
108                     0 /* tag */,
109                     kFontHeaderSize /* offset */,
110                     table_entries.get(),
111                     &output_length))
112     return PP_ERROR_FAILED;
113   DCHECK(output_length == num_tables * kTableEntrySize);
114
115   tags->resize(num_tables);
116   for (uint16_t i = 0; i < num_tables; i++) {
117     uint8_t* entry = table_entries.get() + i * kTableEntrySize;
118     uint32_t tag = static_cast<uint32_t>(entry[0]) << 24 |
119                    static_cast<uint32_t>(entry[1]) << 16 |
120                    static_cast<uint32_t>(entry[2]) << 8 |
121                    static_cast<uint32_t>(entry[3]);
122     (*tags)[i] = tag;
123   }
124
125   return num_tables;
126 }
127
128 int32_t PepperTrueTypeFontLinux::GetTable(uint32_t table_tag,
129                                           int32_t offset,
130                                           int32_t max_data_length,
131                                           std::string* data) {
132   // Get the size of the font data first.
133   size_t table_size = 0;
134   // Tags are byte swapped on Linux.
135   table_tag = base::ByteSwap(table_tag);
136   if (!GetFontTable(fd_, table_tag, offset, NULL, &table_size))
137     return PP_ERROR_FAILED;
138   // Only retrieve as much as the caller requested.
139   table_size = std::min(table_size, static_cast<size_t>(max_data_length));
140   data->resize(table_size);
141   if (!GetFontTable(fd_,
142                     table_tag,
143                     offset,
144                     reinterpret_cast<uint8_t*>(&(*data)[0]),
145                     &table_size))
146     return PP_ERROR_FAILED;
147
148   return base::checked_cast<int32_t>(table_size);
149 }
150
151 }  // namespace
152
153 // static
154 PepperTrueTypeFont* PepperTrueTypeFont::Create(
155     const ppapi::proxy::SerializedTrueTypeFontDesc& desc) {
156   return new PepperTrueTypeFontLinux(desc);
157 }
158
159 }  // namespace content