Home | History | Annotate | Download | only in pepper
      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