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.
5 #include "base/compiler_specific.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/safe_numerics.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"
18 class PepperTrueTypeFontLinux : public PepperTrueTypeFont {
20 explicit PepperTrueTypeFontLinux(
21 const ppapi::proxy::SerializedTrueTypeFontDesc& desc);
22 virtual ~PepperTrueTypeFontLinux() OVERRIDE;
24 // PepperTrueTypeFont overrides.
25 virtual bool IsValid() OVERRIDE;
26 virtual int32_t Describe(
27 ppapi::proxy::SerializedTrueTypeFontDesc* desc) OVERRIDE;
28 virtual int32_t GetTableTags(std::vector<uint32_t>* tags) OVERRIDE;
29 virtual int32_t GetTable(uint32_t table_tag,
31 int32_t max_data_length,
32 std::string* data) OVERRIDE;
34 // Save creation parameters here and use these to implement Describe.
35 // TODO(bbudge) Modify content API to return results of font matching and
37 ppapi::proxy::SerializedTrueTypeFontDesc desc_;
40 DISALLOW_COPY_AND_ASSIGN(PepperTrueTypeFontLinux);
43 PepperTrueTypeFontLinux::PepperTrueTypeFontLinux(
44 const ppapi::proxy::SerializedTrueTypeFontDesc& desc) :
46 // If no face is provided, convert family to the platform defaults. These
47 // names should be mapped by FontConfig to an appropriate default font.
48 if (desc_.family.empty()) {
49 switch (desc_.generic_family) {
50 case PP_TRUETYPEFONTFAMILY_SERIF:
51 desc_.family = "serif";
53 case PP_TRUETYPEFONTFAMILY_SANSSERIF:
54 desc_.family = "sans-serif";
56 case PP_TRUETYPEFONTFAMILY_CURSIVE:
57 desc_.family = "cursive";
59 case PP_TRUETYPEFONTFAMILY_FANTASY:
60 desc_.family = "fantasy";
62 case PP_TRUETYPEFONTFAMILY_MONOSPACE:
63 desc_.family = "monospace";
68 fd_ = MatchFontWithFallback(
70 desc_.weight >= PP_TRUETYPEFONTWEIGHT_BOLD,
71 desc_.style & PP_TRUETYPEFONTSTYLE_ITALIC,
75 PepperTrueTypeFontLinux::~PepperTrueTypeFontLinux() {
78 bool PepperTrueTypeFontLinux::IsValid() {
82 int32_t PepperTrueTypeFontLinux::Describe(
83 ppapi::proxy::SerializedTrueTypeFontDesc* desc) {
88 int32_t PepperTrueTypeFontLinux::GetTableTags(std::vector<uint32_t>* tags) {
89 // Get the 2 byte numTables field at an offset of 4 in the font.
90 uint8_t num_tables_buf[2];
91 size_t output_length = sizeof(num_tables_buf);
92 if (!GetFontTable(fd_,
95 reinterpret_cast<uint8_t*>(&num_tables_buf),
97 return PP_ERROR_FAILED;
98 DCHECK(output_length == sizeof(num_tables_buf));
99 // Font data is stored in big-endian order.
100 uint16_t num_tables = (num_tables_buf[0] << 8) | num_tables_buf[1];
102 // The font has a header, followed by n table entries in its directory.
103 static const size_t kFontHeaderSize = 12;
104 static const size_t kTableEntrySize = 16;
105 output_length = num_tables * kTableEntrySize;
106 scoped_ptr<uint8_t[]> table_entries(new uint8_t[output_length]);
107 // Get the table directory entries, which follow the font header.
108 if (!GetFontTable(fd_,
110 kFontHeaderSize /* offset */,
113 return PP_ERROR_FAILED;
114 DCHECK(output_length == num_tables * kTableEntrySize);
116 tags->resize(num_tables);
117 for (uint16_t i = 0; i < num_tables; i++) {
118 uint8_t* entry = table_entries.get() + i * kTableEntrySize;
119 uint32_t tag = static_cast<uint32_t>(entry[0]) << 24 |
120 static_cast<uint32_t>(entry[1]) << 16 |
121 static_cast<uint32_t>(entry[2]) << 8 |
122 static_cast<uint32_t>(entry[3]);
129 int32_t PepperTrueTypeFontLinux::GetTable(uint32_t table_tag,
131 int32_t max_data_length,
133 // Get the size of the font data first.
134 size_t table_size = 0;
135 // Tags are byte swapped on Linux.
136 table_tag = base::ByteSwap(table_tag);
137 if (!GetFontTable(fd_, table_tag, offset, NULL, &table_size))
138 return PP_ERROR_FAILED;
139 // Only retrieve as much as the caller requested.
140 table_size = std::min(table_size, static_cast<size_t>(max_data_length));
141 data->resize(table_size);
142 if (!GetFontTable(fd_, table_tag, offset,
143 reinterpret_cast<uint8_t*>(&(*data)[0]),
145 return PP_ERROR_FAILED;
147 return base::checked_numeric_cast<int32_t>(table_size);
153 PepperTrueTypeFont* PepperTrueTypeFont::Create(
154 const ppapi::proxy::SerializedTrueTypeFontDesc& desc) {
155 return new PepperTrueTypeFontLinux(desc);
158 } // namespace content