Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / pepper / pepper_truetype_font_linux.cc
1 // Copyright 2014 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/files/scoped_file.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/numerics/safe_conversions.h"
9 #include "base/sys_byteorder.h"
10 #include "content/browser/renderer_host/font_utils_linux.h"
11 #include "content/browser/renderer_host/pepper/pepper_truetype_font.h"
12 #include "content/public/common/child_process_sandbox_support_linux.h"
13 #include "ppapi/c/dev/ppb_truetype_font_dev.h"
14 #include "ppapi/c/pp_errors.h"
15
16 namespace content {
17
18 namespace {
19
20 class PepperTrueTypeFontLinux : public PepperTrueTypeFont {
21  public:
22   PepperTrueTypeFontLinux();
23
24   // PepperTrueTypeFont implementation.
25   int32_t Initialize(ppapi::proxy::SerializedTrueTypeFontDesc* desc) override;
26   int32_t GetTableTags(std::vector<uint32_t>* tags) override;
27   int32_t GetTable(uint32_t table_tag,
28                    int32_t offset,
29                    int32_t max_data_length,
30                    std::string* data) override;
31
32  private:
33   ~PepperTrueTypeFontLinux() override;
34
35   base::ScopedFD fd_;
36
37   DISALLOW_COPY_AND_ASSIGN(PepperTrueTypeFontLinux);
38 };
39
40 PepperTrueTypeFontLinux::PepperTrueTypeFontLinux() {
41 }
42
43 PepperTrueTypeFontLinux::~PepperTrueTypeFontLinux() {
44 }
45
46 int32_t PepperTrueTypeFontLinux::Initialize(
47     ppapi::proxy::SerializedTrueTypeFontDesc* 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_.reset(
71       MatchFontFaceWithFallback(desc->family,
72                                 desc->weight >= PP_TRUETYPEFONTWEIGHT_BOLD,
73                                 desc->style & PP_TRUETYPEFONTSTYLE_ITALIC,
74                                 desc->charset,
75                                 PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT));
76   // TODO(bbudge) Modify content API to return results of font matching and
77   // fallback, so we can update |desc| to reflect that.
78   return fd_.is_valid() ? PP_OK : PP_ERROR_FAILED;
79 }
80
81 int32_t PepperTrueTypeFontLinux::GetTableTags(std::vector<uint32_t>* tags) {
82   if (!fd_.is_valid())
83     return PP_ERROR_FAILED;
84   // Get the 2 byte numTables field at an offset of 4 in the font.
85   uint8_t num_tables_buf[2];
86   size_t output_length = sizeof(num_tables_buf);
87   if (!GetFontTable(fd_.get(),
88                     0 /* tag */,
89                     4 /* offset */,
90                     reinterpret_cast<uint8_t*>(&num_tables_buf),
91                     &output_length))
92     return PP_ERROR_FAILED;
93   DCHECK(output_length == sizeof(num_tables_buf));
94   // Font data is stored in big-endian order.
95   uint16_t num_tables = (num_tables_buf[0] << 8) | num_tables_buf[1];
96
97   // The font has a header, followed by n table entries in its directory.
98   static const size_t kFontHeaderSize = 12;
99   static const size_t kTableEntrySize = 16;
100   output_length = num_tables * kTableEntrySize;
101   scoped_ptr<uint8_t[]> table_entries(new uint8_t[output_length]);
102   // Get the table directory entries, which follow the font header.
103   if (!GetFontTable(fd_.get(),
104                     0 /* tag */,
105                     kFontHeaderSize /* offset */,
106                     table_entries.get(),
107                     &output_length))
108     return PP_ERROR_FAILED;
109   DCHECK(output_length == num_tables * kTableEntrySize);
110
111   tags->resize(num_tables);
112   for (uint16_t i = 0; i < num_tables; i++) {
113     uint8_t* entry = table_entries.get() + i * kTableEntrySize;
114     uint32_t tag = static_cast<uint32_t>(entry[0]) << 24 |
115                    static_cast<uint32_t>(entry[1]) << 16 |
116                    static_cast<uint32_t>(entry[2]) << 8 |
117                    static_cast<uint32_t>(entry[3]);
118     (*tags)[i] = tag;
119   }
120
121   return num_tables;
122 }
123
124 int32_t PepperTrueTypeFontLinux::GetTable(uint32_t table_tag,
125                                           int32_t offset,
126                                           int32_t max_data_length,
127                                           std::string* data) {
128   if (!fd_.is_valid())
129     return PP_ERROR_FAILED;
130   // Get the size of the font data first.
131   size_t table_size = 0;
132   // Tags are byte swapped on Linux.
133   table_tag = base::ByteSwap(table_tag);
134   if (!GetFontTable(fd_.get(), table_tag, offset, NULL, &table_size))
135     return PP_ERROR_FAILED;
136   // Only retrieve as much as the caller requested.
137   table_size = std::min(table_size, static_cast<size_t>(max_data_length));
138   data->resize(table_size);
139   if (!GetFontTable(fd_.get(),
140                     table_tag,
141                     offset,
142                     reinterpret_cast<uint8_t*>(&(*data)[0]),
143                     &table_size))
144     return PP_ERROR_FAILED;
145
146   return base::checked_cast<int32_t>(table_size);
147 }
148
149 }  // namespace
150
151 // static
152 PepperTrueTypeFont* PepperTrueTypeFont::Create() {
153   return new PepperTrueTypeFontLinux();
154 }
155
156 }  // namespace content