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/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" 13 14 namespace content { 15 16 namespace { 17 18 class PepperTrueTypeFontLinux : public PepperTrueTypeFont { 19 public: 20 explicit PepperTrueTypeFontLinux( 21 const ppapi::proxy::SerializedTrueTypeFontDesc& desc); 22 virtual ~PepperTrueTypeFontLinux() OVERRIDE; 23 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, 30 int32_t offset, 31 int32_t max_data_length, 32 std::string* data) OVERRIDE; 33 private: 34 // Save creation parameters here and use these to implement Describe. 35 // TODO(bbudge) Modify content API to return results of font matching and 36 // fallback. 37 ppapi::proxy::SerializedTrueTypeFontDesc desc_; 38 int fd_; 39 40 DISALLOW_COPY_AND_ASSIGN(PepperTrueTypeFontLinux); 41 }; 42 43 PepperTrueTypeFontLinux::PepperTrueTypeFontLinux( 44 const ppapi::proxy::SerializedTrueTypeFontDesc& desc) : 45 desc_(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"; 52 break; 53 case PP_TRUETYPEFONTFAMILY_SANSSERIF: 54 desc_.family = "sans-serif"; 55 break; 56 case PP_TRUETYPEFONTFAMILY_CURSIVE: 57 desc_.family = "cursive"; 58 break; 59 case PP_TRUETYPEFONTFAMILY_FANTASY: 60 desc_.family = "fantasy"; 61 break; 62 case PP_TRUETYPEFONTFAMILY_MONOSPACE: 63 desc_.family = "monospace"; 64 break; 65 } 66 } 67 68 fd_ = MatchFontWithFallback( 69 desc_.family.c_str(), 70 desc_.weight >= PP_TRUETYPEFONTWEIGHT_BOLD, 71 desc_.style & PP_TRUETYPEFONTSTYLE_ITALIC, 72 desc_.charset); 73 } 74 75 PepperTrueTypeFontLinux::~PepperTrueTypeFontLinux() { 76 } 77 78 bool PepperTrueTypeFontLinux::IsValid() { 79 return fd_ != -1; 80 } 81 82 int32_t PepperTrueTypeFontLinux::Describe( 83 ppapi::proxy::SerializedTrueTypeFontDesc* desc) { 84 *desc = desc_; 85 return PP_OK; 86 } 87 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_, 93 0 /* tag */, 94 4 /* offset */, 95 reinterpret_cast<uint8_t*>(&num_tables_buf), 96 &output_length)) 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]; 101 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_, 109 0 /* tag */, 110 kFontHeaderSize /* offset */, 111 table_entries.get(), 112 &output_length)) 113 return PP_ERROR_FAILED; 114 DCHECK(output_length == num_tables * kTableEntrySize); 115 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]); 123 (*tags)[i] = tag; 124 } 125 126 return num_tables; 127 } 128 129 int32_t PepperTrueTypeFontLinux::GetTable(uint32_t table_tag, 130 int32_t offset, 131 int32_t max_data_length, 132 std::string* data) { 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]), 144 &table_size)) 145 return PP_ERROR_FAILED; 146 147 return base::checked_numeric_cast<int32_t>(table_size); 148 } 149 150 } // namespace 151 152 // static 153 PepperTrueTypeFont* PepperTrueTypeFont::Create( 154 const ppapi::proxy::SerializedTrueTypeFontDesc& desc) { 155 return new PepperTrueTypeFontLinux(desc); 156 } 157 158 } // namespace content 159 160