// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/renderer_host/pepper/pepper_truetype_font.h"

#include <windows.h>
#include <set>

#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "base/sys_byteorder.h"
#include "base/win/scoped_gdi_object.h"
#include "base/win/scoped_hdc.h"
#include "base/win/scoped_select_object.h"
#include "ppapi/c/dev/ppb_truetype_font_dev.h"
#include "ppapi/c/pp_errors.h"

namespace content {

namespace {

class PepperTrueTypeFontWin : public PepperTrueTypeFont {
 public:
  PepperTrueTypeFontWin();

  // PepperTrueTypeFont implementation.
  virtual int32_t Initialize(
      ppapi::proxy::SerializedTrueTypeFontDesc* desc) OVERRIDE;
  virtual int32_t GetTableTags(std::vector<uint32_t>* tags) OVERRIDE;
  virtual int32_t GetTable(uint32_t table_tag,
                           int32_t offset,
                           int32_t max_data_length,
                           std::string* data) OVERRIDE;

 private:
  virtual ~PepperTrueTypeFontWin();

  DWORD GetFontData(HDC hdc,
                    DWORD table,
                    DWORD offset,
                    LPVOID buffer,
                    DWORD length);

  base::win::ScopedHFONT font_;

  DISALLOW_COPY_AND_ASSIGN(PepperTrueTypeFontWin);
};

PepperTrueTypeFontWin::PepperTrueTypeFontWin() {
}

PepperTrueTypeFontWin::~PepperTrueTypeFontWin() {
}

int32_t PepperTrueTypeFontWin::Initialize(
    ppapi::proxy::SerializedTrueTypeFontDesc* desc) {
  DWORD pitch_and_family = DEFAULT_PITCH;
  switch (desc->generic_family) {
    case PP_TRUETYPEFONTFAMILY_SERIF:
      pitch_and_family |= FF_ROMAN;
      break;
    case PP_TRUETYPEFONTFAMILY_SANSSERIF:
      pitch_and_family |= FF_SWISS;
      break;
    case PP_TRUETYPEFONTFAMILY_CURSIVE:
      pitch_and_family |= FF_SCRIPT;
      break;
    case PP_TRUETYPEFONTFAMILY_FANTASY:
      pitch_and_family |= FF_DECORATIVE;
      break;
    case PP_TRUETYPEFONTFAMILY_MONOSPACE:
      pitch_and_family |= FF_MODERN;
      break;
  }
  // TODO(bbudge) support widths (extended, condensed).

  font_.Set(CreateFont(0 /* height */,
                       0 /* width */,
                       0 /* escapement */,
                       0 /* orientation */,
                       desc->weight,  // our weight enum matches Windows.
                       (desc->style & PP_TRUETYPEFONTSTYLE_ITALIC) ? 1 : 0,
                       0 /* underline */,
                       0 /* strikeout */,
                       desc->charset,       // our charset enum matches Windows.
                       OUT_OUTLINE_PRECIS,  // truetype and other outline fonts
                       CLIP_DEFAULT_PRECIS,
                       DEFAULT_QUALITY,
                       pitch_and_family,
                       base::UTF8ToUTF16(desc->family).c_str()));
  if (!font_.Get())
    return PP_ERROR_FAILED;

  LOGFONT font_desc;
  if (!::GetObject(font_.Get(), sizeof(LOGFONT), &font_desc))
    return PP_ERROR_FAILED;

  switch (font_desc.lfPitchAndFamily & 0xF0) {  // Top 4 bits are family.
    case FF_ROMAN:
      desc->generic_family = PP_TRUETYPEFONTFAMILY_SERIF;
      break;
    case FF_SWISS:
      desc->generic_family = PP_TRUETYPEFONTFAMILY_SANSSERIF;
      break;
    case FF_SCRIPT:
      desc->generic_family = PP_TRUETYPEFONTFAMILY_CURSIVE;
      break;
    case FF_DECORATIVE:
      desc->generic_family = PP_TRUETYPEFONTFAMILY_FANTASY;
      break;
    case FF_MODERN:
      desc->generic_family = PP_TRUETYPEFONTFAMILY_MONOSPACE;
      break;
  }

  desc->style = font_desc.lfItalic ? PP_TRUETYPEFONTSTYLE_ITALIC
                                   : PP_TRUETYPEFONTSTYLE_NORMAL;
  desc->weight = static_cast<PP_TrueTypeFontWeight_Dev>(font_desc.lfWeight);
  desc->width = PP_TRUETYPEFONTWIDTH_NORMAL;
  desc->charset = static_cast<PP_TrueTypeFontCharset_Dev>(font_desc.lfCharSet);

  // To get the face name, select the font and query for the name. GetObject
  // doesn't fill in the name field of the LOGFONT structure.
  base::win::ScopedCreateDC hdc(::CreateCompatibleDC(NULL));
  if (hdc) {
    base::win::ScopedSelectObject select_object(hdc, font_.Get());
    WCHAR name[LF_FACESIZE];
    GetTextFace(hdc, LF_FACESIZE, name);
    desc->family = base::UTF16ToUTF8(name);
  }

  return PP_OK;
}

int32_t PepperTrueTypeFontWin::GetTableTags(std::vector<uint32_t>* tags) {
  if (!font_.Get())
    return PP_ERROR_FAILED;

  base::win::ScopedCreateDC hdc(::CreateCompatibleDC(NULL));
  if (!hdc)
    return PP_ERROR_FAILED;

  base::win::ScopedSelectObject select_object(hdc, font_.Get());

  // Get the whole font header.
  static const DWORD kFontHeaderSize = 12;
  uint8_t header_buf[kFontHeaderSize];
  if (GetFontData(hdc, 0, 0, header_buf, kFontHeaderSize) == GDI_ERROR)
    return PP_ERROR_FAILED;

  // The numTables follows a 4 byte scalerType tag. Font data is stored in
  // big-endian order.
  DWORD num_tables = (header_buf[4] << 8) | header_buf[5];

  // The size in bytes of an entry in the table directory.
  static const DWORD kDirectoryEntrySize = 16;
  DWORD directory_size = num_tables * kDirectoryEntrySize;
  scoped_ptr<uint8_t[]> directory(new uint8_t[directory_size]);
  // Get the table directory entries after the font header.
  if (GetFontData(
          hdc, 0 /* tag */, kFontHeaderSize, directory.get(), directory_size) ==
      GDI_ERROR)
    return PP_ERROR_FAILED;

  tags->resize(num_tables);
  for (DWORD i = 0; i < num_tables; i++) {
    const uint8_t* entry = directory.get() + i * kDirectoryEntrySize;
    uint32_t tag = static_cast<uint32_t>(entry[0]) << 24 |
                   static_cast<uint32_t>(entry[1]) << 16 |
                   static_cast<uint32_t>(entry[2]) << 8 |
                   static_cast<uint32_t>(entry[3]);
    (*tags)[i] = tag;
  }

  return num_tables;
}

int32_t PepperTrueTypeFontWin::GetTable(uint32_t table_tag,
                                        int32_t offset,
                                        int32_t max_data_length,
                                        std::string* data) {
  if (!font_.Get())
    return PP_ERROR_FAILED;

  base::win::ScopedCreateDC hdc(::CreateCompatibleDC(NULL));
  if (!hdc)
    return PP_ERROR_FAILED;

  base::win::ScopedSelectObject select_object(hdc, font_.Get());

  // Tags are byte swapped on Windows.
  table_tag = base::ByteSwap(table_tag);
  // Get the size of the font table first.
  DWORD table_size = GetFontData(hdc, table_tag, 0, NULL, 0);
  if (table_size == GDI_ERROR)
    return PP_ERROR_FAILED;

  DWORD safe_offset = std::min(static_cast<DWORD>(offset), table_size);
  DWORD safe_length =
      std::min(table_size - safe_offset, static_cast<DWORD>(max_data_length));
  data->resize(safe_length);
  if (safe_length == 0) {
    table_size = 0;
  } else {
    table_size = GetFontData(hdc,
                             table_tag,
                             safe_offset,
                             reinterpret_cast<uint8_t*>(&(*data)[0]),
                             safe_length);
    if (table_size == GDI_ERROR)
      return PP_ERROR_FAILED;
  }
  return static_cast<int32_t>(table_size);
}

DWORD PepperTrueTypeFontWin::GetFontData(HDC hdc,
                                         DWORD table,
                                         DWORD offset,
                                         void* buffer,
                                         DWORD length) {
  // If this is a zero byte read, return a successful result.
  if (buffer && !length)
    return 0;

  return ::GetFontData(hdc, table, offset, buffer, length);
}

}  // namespace

// static
PepperTrueTypeFont* PepperTrueTypeFont::Create() {
  return new PepperTrueTypeFontWin();
}

}  // namespace content
