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.
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"
20 class PepperTrueTypeFontLinux : public PepperTrueTypeFont {
22 PepperTrueTypeFontLinux();
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,
29 int32_t max_data_length,
30 std::string* data) override;
33 ~PepperTrueTypeFontLinux() override;
37 DISALLOW_COPY_AND_ASSIGN(PepperTrueTypeFontLinux);
40 PepperTrueTypeFontLinux::PepperTrueTypeFontLinux() {
43 PepperTrueTypeFontLinux::~PepperTrueTypeFontLinux() {
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";
55 case PP_TRUETYPEFONTFAMILY_SANSSERIF:
56 desc->family = "sans-serif";
58 case PP_TRUETYPEFONTFAMILY_CURSIVE:
59 desc->family = "cursive";
61 case PP_TRUETYPEFONTFAMILY_FANTASY:
62 desc->family = "fantasy";
64 case PP_TRUETYPEFONTFAMILY_MONOSPACE:
65 desc->family = "monospace";
71 MatchFontFaceWithFallback(desc->family,
72 desc->weight >= PP_TRUETYPEFONTWEIGHT_BOLD,
73 desc->style & PP_TRUETYPEFONTSTYLE_ITALIC,
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;
81 int32_t PepperTrueTypeFontLinux::GetTableTags(std::vector<uint32_t>* tags) {
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(),
90 reinterpret_cast<uint8_t*>(&num_tables_buf),
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];
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(),
105 kFontHeaderSize /* offset */,
108 return PP_ERROR_FAILED;
109 DCHECK(output_length == num_tables * kTableEntrySize);
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]);
124 int32_t PepperTrueTypeFontLinux::GetTable(uint32_t table_tag,
126 int32_t max_data_length,
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(),
142 reinterpret_cast<uint8_t*>(&(*data)[0]),
144 return PP_ERROR_FAILED;
146 return base::checked_cast<int32_t>(table_size);
152 PepperTrueTypeFont* PepperTrueTypeFont::Create() {
153 return new PepperTrueTypeFontLinux();
156 } // namespace content