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

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fpdfapi/fpdf_font/cpdf_truetypefont.h"

#include "core/fpdfapi/fpdf_font/font_int.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "core/fxge/include/fx_font.h"

namespace {

const uint8_t kPrefix[4] = {0x00, 0xf0, 0xf1, 0xf2};

}  // namespace

CPDF_TrueTypeFont::CPDF_TrueTypeFont() {}

bool CPDF_TrueTypeFont::IsTrueTypeFont() const {
  return true;
}

const CPDF_TrueTypeFont* CPDF_TrueTypeFont::AsTrueTypeFont() const {
  return this;
}

CPDF_TrueTypeFont* CPDF_TrueTypeFont::AsTrueTypeFont() {
  return this;
}

bool CPDF_TrueTypeFont::Load() {
  return LoadCommon();
}

void CPDF_TrueTypeFont::LoadGlyphMap() {
  if (!m_Font.GetFace())
    return;

  int baseEncoding = m_BaseEncoding;
  if (m_pFontFile && m_Font.GetFace()->num_charmaps > 0 &&
      (baseEncoding == PDFFONT_ENCODING_MACROMAN ||
       baseEncoding == PDFFONT_ENCODING_WINANSI) &&
      (m_Flags & PDFFONT_SYMBOLIC)) {
    FX_BOOL bSupportWin = FALSE;
    FX_BOOL bSupportMac = FALSE;
    for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.GetFace()); i++) {
      int platform_id = FXFT_Get_Charmap_PlatformID(
          FXFT_Get_Face_Charmaps(m_Font.GetFace())[i]);
      if (platform_id == 0 || platform_id == 3) {
        bSupportWin = TRUE;
      } else if (platform_id == 0 || platform_id == 1) {
        bSupportMac = TRUE;
      }
    }
    if (baseEncoding == PDFFONT_ENCODING_WINANSI && !bSupportWin) {
      baseEncoding =
          bSupportMac ? PDFFONT_ENCODING_MACROMAN : PDFFONT_ENCODING_BUILTIN;
    } else if (baseEncoding == PDFFONT_ENCODING_MACROMAN && !bSupportMac) {
      baseEncoding =
          bSupportWin ? PDFFONT_ENCODING_WINANSI : PDFFONT_ENCODING_BUILTIN;
    }
  }
  if (((baseEncoding == PDFFONT_ENCODING_MACROMAN ||
        baseEncoding == PDFFONT_ENCODING_WINANSI) &&
       m_CharNames.empty()) ||
      (m_Flags & PDFFONT_NONSYMBOLIC)) {
    if (!FXFT_Has_Glyph_Names(m_Font.GetFace()) &&
        (!m_Font.GetFace()->num_charmaps || !m_Font.GetFace()->charmaps)) {
      int nStartChar = m_pFontDict->GetIntegerFor("FirstChar");
      if (nStartChar < 0 || nStartChar > 255)
        return;

      int charcode = 0;
      for (; charcode < nStartChar; charcode++) {
        m_GlyphIndex[charcode] = 0;
      }
      uint16_t nGlyph = charcode - nStartChar + 3;
      for (; charcode < 256; charcode++, nGlyph++) {
        m_GlyphIndex[charcode] = nGlyph;
      }
      return;
    }
    bool bMSUnicode = FT_UseTTCharmap(m_Font.GetFace(), 3, 1);
    bool bMacRoman = false;
    bool bMSSymbol = false;
    if (!bMSUnicode) {
      if (m_Flags & PDFFONT_NONSYMBOLIC) {
        bMacRoman = FT_UseTTCharmap(m_Font.GetFace(), 1, 0);
        bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.GetFace(), 3, 0);
      } else {
        bMSSymbol = FT_UseTTCharmap(m_Font.GetFace(), 3, 0);
        bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.GetFace(), 1, 0);
      }
    }
    FX_BOOL bToUnicode = m_pFontDict->KeyExist("ToUnicode");
    for (int charcode = 0; charcode < 256; charcode++) {
      const FX_CHAR* name =
          GetAdobeCharName(baseEncoding, m_CharNames, charcode);
      if (!name) {
        m_GlyphIndex[charcode] =
            m_pFontFile ? FXFT_Get_Char_Index(m_Font.GetFace(), charcode) : -1;
        continue;
      }
      m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
      if (bMSSymbol) {
        for (size_t j = 0; j < FX_ArraySize(kPrefix); j++) {
          uint16_t unicode = kPrefix[j] * 256 + charcode;
          m_GlyphIndex[charcode] =
              FXFT_Get_Char_Index(m_Font.GetFace(), unicode);
          if (m_GlyphIndex[charcode]) {
            break;
          }
        }
      } else if (m_Encoding.m_Unicodes[charcode]) {
        if (bMSUnicode) {
          m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
              m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]);
        } else if (bMacRoman) {
          uint32_t maccode = FT_CharCodeFromUnicode(
              FXFT_ENCODING_APPLE_ROMAN, m_Encoding.m_Unicodes[charcode]);
          if (!maccode) {
            m_GlyphIndex[charcode] =
                FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
          } else {
            m_GlyphIndex[charcode] =
                FXFT_Get_Char_Index(m_Font.GetFace(), maccode);
          }
        }
      }
      if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff) &&
          name) {
        if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) {
          m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 32);
        } else {
          m_GlyphIndex[charcode] =
              FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
          if (m_GlyphIndex[charcode] == 0) {
            if (bToUnicode) {
              CFX_WideString wsUnicode = UnicodeFromCharCode(charcode);
              if (!wsUnicode.IsEmpty()) {
                m_GlyphIndex[charcode] =
                    FXFT_Get_Char_Index(m_Font.GetFace(), wsUnicode[0]);
                m_Encoding.m_Unicodes[charcode] = wsUnicode[0];
              }
            }
            if (m_GlyphIndex[charcode] == 0) {
              m_GlyphIndex[charcode] =
                  FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
            }
          }
        }
      }
    }
    return;
  }
  if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) {
    bool bFound = false;
    for (int charcode = 0; charcode < 256; charcode++) {
      for (size_t j = 0; j < FX_ArraySize(kPrefix); j++) {
        uint16_t unicode = kPrefix[j] * 256 + charcode;
        m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), unicode);
        if (m_GlyphIndex[charcode]) {
          bFound = true;
          break;
        }
      }
    }
    if (bFound) {
      if (baseEncoding != PDFFONT_ENCODING_BUILTIN) {
        for (int charcode = 0; charcode < 256; charcode++) {
          const FX_CHAR* name =
              GetAdobeCharName(baseEncoding, m_CharNames, charcode);
          if (name)
            m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
        }
      } else if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) {
        for (int charcode = 0; charcode < 256; charcode++) {
          m_Encoding.m_Unicodes[charcode] =
              FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode);
        }
      }
      return;
    }
  }
  if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) {
    bool bFound = false;
    for (int charcode = 0; charcode < 256; charcode++) {
      m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
      m_Encoding.m_Unicodes[charcode] =
          FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode);
      if (m_GlyphIndex[charcode]) {
        bFound = true;
      }
    }
    if (m_pFontFile || bFound)
      return;
  }
  if (FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE) == 0) {
    bool bFound = false;
    const uint16_t* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding);
    for (int charcode = 0; charcode < 256; charcode++) {
      if (m_pFontFile) {
        m_Encoding.m_Unicodes[charcode] = charcode;
      } else {
        const FX_CHAR* name = GetAdobeCharName(0, m_CharNames, charcode);
        if (name)
          m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
        else if (pUnicodes)
          m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode];
      }
      m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
          m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]);
      if (m_GlyphIndex[charcode])
        bFound = true;
    }
    if (bFound)
      return;
  }
  for (int charcode = 0; charcode < 256; charcode++)
    m_GlyphIndex[charcode] = charcode;
}
