// Copyright 2016 The PDFium Authors
// 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/fxge/cfx_glyphcache.h"

#include <stdarg.h>

#include <algorithm>
#include <limits>
#include <memory>
#include <utility>

#include "build/build_config.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxge/cfx_defaultrenderdevice.h"
#include "core/fxge/cfx_font.h"
#include "core/fxge/cfx_fontmgr.h"
#include "core/fxge/cfx_gemodule.h"
#include "core/fxge/cfx_glyphbitmap.h"
#include "core/fxge/cfx_path.h"
#include "core/fxge/cfx_substfont.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "core/fxge/freetype/fx_freetype.h"
#include "core/fxge/scoped_font_transform.h"
#include "third_party/base/numerics/safe_math.h"

#if defined(_SKIA_SUPPORT_)
#include "third_party/skia/include/core/SkStream.h"  // nogncheck
#include "third_party/skia/include/core/SkTypeface.h"  // nogncheck

#if BUILDFLAG(IS_WIN)
#include "third_party/skia/include/core/SkFontMgr.h"  // nogncheck
#include "third_party/skia/include/ports/SkFontMgr_empty.h"  // nogncheck
#endif
#endif

#if BUILDFLAG(IS_APPLE)
#include "core/fxge/cfx_textrenderoptions.h"
#endif

namespace {

constexpr uint32_t kInvalidGlyphIndex = static_cast<uint32_t>(-1);

constexpr int kMaxGlyphDimension = 2048;

struct UniqueKeyGen {
  void Generate(int count, ...);

  int key_len_;
  char key_[128];
};

void UniqueKeyGen::Generate(int count, ...) {
  va_list argList;
  va_start(argList, count);
  for (int i = 0; i < count; i++) {
    int p = va_arg(argList, int);
    reinterpret_cast<uint32_t*>(key_)[i] = p;
  }
  va_end(argList);
  key_len_ = count * sizeof(uint32_t);
}

void GenKey(UniqueKeyGen* pKeyGen,
            const CFX_Font* pFont,
            const CFX_Matrix& matrix,
            int dest_width,
            int anti_alias,
            bool bNative) {
  int nMatrixA = static_cast<int>(matrix.a * 10000);
  int nMatrixB = static_cast<int>(matrix.b * 10000);
  int nMatrixC = static_cast<int>(matrix.c * 10000);
  int nMatrixD = static_cast<int>(matrix.d * 10000);

#if BUILDFLAG(IS_APPLE)
  if (bNative) {
    if (pFont->GetSubstFont()) {
      pKeyGen->Generate(10, nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width,
                        anti_alias, pFont->GetSubstFont()->m_Weight,
                        pFont->GetSubstFont()->m_ItalicAngle,
                        pFont->IsVertical(), 3);
    } else {
      pKeyGen->Generate(7, nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width,
                        anti_alias, 3);
    }
    return;
  }
#else
  CHECK(!bNative);
#endif

  if (pFont->GetSubstFont()) {
    pKeyGen->Generate(9, nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width,
                      anti_alias, pFont->GetSubstFont()->m_Weight,
                      pFont->GetSubstFont()->m_ItalicAngle,
                      pFont->IsVertical());
  } else {
    pKeyGen->Generate(6, nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width,
                      anti_alias);
  }
}

}  // namespace

CFX_GlyphCache::CFX_GlyphCache(RetainPtr<CFX_Face> face)
    : m_Face(std::move(face)) {}

CFX_GlyphCache::~CFX_GlyphCache() = default;

std::unique_ptr<CFX_GlyphBitmap> CFX_GlyphCache::RenderGlyph(
    const CFX_Font* pFont,
    uint32_t glyph_index,
    bool bFontStyle,
    const CFX_Matrix& matrix,
    int dest_width,
    int anti_alias) {
  if (!GetFaceRec())
    return nullptr;

  FT_Matrix ft_matrix;
  ft_matrix.xx = matrix.a / 64 * 65536;
  ft_matrix.xy = matrix.c / 64 * 65536;
  ft_matrix.yx = matrix.b / 64 * 65536;
  ft_matrix.yy = matrix.d / 64 * 65536;
  bool bUseCJKSubFont = false;
  const CFX_SubstFont* pSubstFont = pFont->GetSubstFont();
  if (pSubstFont) {
    bUseCJKSubFont = pSubstFont->m_bSubstCJK && bFontStyle;
    int angle;
    if (bUseCJKSubFont)
      angle = pSubstFont->m_bItalicCJK ? -15 : 0;
    else
      angle = pSubstFont->m_ItalicAngle;
    if (angle) {
      int skew = CFX_Font::GetSkewFromAngle(angle);
      if (pFont->IsVertical())
        ft_matrix.yx += ft_matrix.yy * skew / 100;
      else
        ft_matrix.xy -= ft_matrix.xx * skew / 100;
    }
    if (pSubstFont->IsBuiltInGenericFont()) {
      pFont->AdjustMMParams(glyph_index, dest_width,
                            pFont->GetSubstFont()->m_Weight);
    }
  }

  ScopedFontTransform scoped_transform(GetFace(), &ft_matrix);
  int load_flags = FT_LOAD_NO_BITMAP | FT_LOAD_PEDANTIC;
  if (!(GetFaceRec()->face_flags & FT_FACE_FLAG_SFNT))
    load_flags |= FT_LOAD_NO_HINTING;
  int error = FT_Load_Glyph(GetFaceRec(), glyph_index, load_flags);
  if (error) {
    // if an error is returned, try to reload glyphs without hinting.
    if (load_flags & FT_LOAD_NO_HINTING)
      return nullptr;

    load_flags |= FT_LOAD_NO_HINTING;
    load_flags &= ~FT_LOAD_PEDANTIC;
    error = FT_Load_Glyph(GetFaceRec(), glyph_index, load_flags);
    if (error)
      return nullptr;
  }

  int weight;
  if (bUseCJKSubFont)
    weight = pSubstFont->m_WeightCJK;
  else
    weight = pSubstFont ? pSubstFont->m_Weight : 0;
  if (pSubstFont && !pSubstFont->IsBuiltInGenericFont() && weight > 400) {
    uint32_t index = (weight - 400) / 10;
    pdfium::base::CheckedNumeric<signed long> level =
        CFX_Font::GetWeightLevel(pSubstFont->m_Charset, index);
    if (level.ValueOrDefault(-1) < 0)
      return nullptr;

    level = level *
            (abs(static_cast<int>(ft_matrix.xx)) +
             abs(static_cast<int>(ft_matrix.xy))) /
            36655;
    FT_Outline_Embolden(FXFT_Get_Glyph_Outline(GetFaceRec()),
                        level.ValueOrDefault(0));
  }
  FT_Library_SetLcdFilter(CFX_GEModule::Get()->GetFontMgr()->GetFTLibrary(),
                          FT_LCD_FILTER_DEFAULT);
  error = FXFT_Render_Glyph(GetFaceRec(), anti_alias);
  if (error)
    return nullptr;

  int bmwidth = FXFT_Get_Bitmap_Width(FXFT_Get_Glyph_Bitmap(GetFaceRec()));
  int bmheight = FXFT_Get_Bitmap_Rows(FXFT_Get_Glyph_Bitmap(GetFaceRec()));
  if (bmwidth > kMaxGlyphDimension || bmheight > kMaxGlyphDimension)
    return nullptr;
  int dib_width = bmwidth;
  auto pGlyphBitmap =
      std::make_unique<CFX_GlyphBitmap>(FXFT_Get_Glyph_BitmapLeft(GetFaceRec()),
                                        FXFT_Get_Glyph_BitmapTop(GetFaceRec()));
  pGlyphBitmap->GetBitmap()->Create(dib_width, bmheight,
                                    anti_alias == FT_RENDER_MODE_MONO
                                        ? FXDIB_Format::k1bppMask
                                        : FXDIB_Format::k8bppMask);
  int dest_pitch = pGlyphBitmap->GetBitmap()->GetPitch();
  int src_pitch = FXFT_Get_Bitmap_Pitch(FXFT_Get_Glyph_Bitmap(GetFaceRec()));
  uint8_t* pDestBuf = pGlyphBitmap->GetBitmap()->GetBuffer().data();
  uint8_t* pSrcBuf = static_cast<uint8_t*>(
      FXFT_Get_Bitmap_Buffer(FXFT_Get_Glyph_Bitmap(GetFaceRec())));
  if (anti_alias != FT_RENDER_MODE_MONO &&
      FXFT_Get_Bitmap_PixelMode(FXFT_Get_Glyph_Bitmap(GetFaceRec())) ==
          FT_PIXEL_MODE_MONO) {
    int bytes = anti_alias == FT_RENDER_MODE_LCD ? 3 : 1;
    for (int i = 0; i < bmheight; i++) {
      for (int n = 0; n < bmwidth; n++) {
        uint8_t data =
            (pSrcBuf[i * src_pitch + n / 8] & (0x80 >> (n % 8))) ? 255 : 0;
        for (int b = 0; b < bytes; b++)
          pDestBuf[i * dest_pitch + n * bytes + b] = data;
      }
    }
  } else {
    memset(pDestBuf, 0, dest_pitch * bmheight);
    int rowbytes = std::min(abs(src_pitch), dest_pitch);
    for (int row = 0; row < bmheight; row++)
      memcpy(pDestBuf + row * dest_pitch, pSrcBuf + row * src_pitch, rowbytes);
  }
  return pGlyphBitmap;
}

const CFX_Path* CFX_GlyphCache::LoadGlyphPath(const CFX_Font* pFont,
                                              uint32_t glyph_index,
                                              int dest_width) {
  if (!GetFaceRec() || glyph_index == kInvalidGlyphIndex)
    return nullptr;

  const auto* pSubstFont = pFont->GetSubstFont();
  int weight = pSubstFont ? pSubstFont->m_Weight : 0;
  int angle = pSubstFont ? pSubstFont->m_ItalicAngle : 0;
  bool vertical = pSubstFont && pFont->IsVertical();
  const PathMapKey key =
      std::make_tuple(glyph_index, dest_width, weight, angle, vertical);
  auto it = m_PathMap.find(key);
  if (it != m_PathMap.end())
    return it->second.get();

  m_PathMap[key] = pFont->LoadGlyphPathImpl(glyph_index, dest_width);
  return m_PathMap[key].get();
}

const CFX_GlyphBitmap* CFX_GlyphCache::LoadGlyphBitmap(
    const CFX_Font* pFont,
    uint32_t glyph_index,
    bool bFontStyle,
    const CFX_Matrix& matrix,
    int dest_width,
    int anti_alias,
    CFX_TextRenderOptions* text_options) {
  if (glyph_index == kInvalidGlyphIndex)
    return nullptr;

  UniqueKeyGen keygen;
#if BUILDFLAG(IS_APPLE)
  const bool bNative = text_options->native_text;
#else
  const bool bNative = false;
#endif
  GenKey(&keygen, pFont, matrix, dest_width, anti_alias, bNative);
  ByteString FaceGlyphsKey(keygen.key_, keygen.key_len_);

#if BUILDFLAG(IS_APPLE)
  const bool bDoLookUp = !text_options->native_text ||
                         CFX_DefaultRenderDevice::SkiaIsDefaultRenderer();
#else
  const bool bDoLookUp = true;
#endif
  if (bDoLookUp) {
    return LookUpGlyphBitmap(pFont, matrix, FaceGlyphsKey, glyph_index,
                             bFontStyle, dest_width, anti_alias);
  }

#if BUILDFLAG(IS_APPLE)
  DCHECK(!CFX_DefaultRenderDevice::SkiaIsDefaultRenderer());

  std::unique_ptr<CFX_GlyphBitmap> pGlyphBitmap;
  auto it = m_SizeMap.find(FaceGlyphsKey);
  if (it != m_SizeMap.end()) {
    SizeGlyphCache* pSizeCache = &(it->second);
    auto it2 = pSizeCache->find(glyph_index);
    if (it2 != pSizeCache->end())
      return it2->second.get();

    pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, matrix,
                                          dest_width, anti_alias);
    if (pGlyphBitmap) {
      CFX_GlyphBitmap* pResult = pGlyphBitmap.get();
      (*pSizeCache)[glyph_index] = std::move(pGlyphBitmap);
      return pResult;
    }
  } else {
    pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, matrix,
                                          dest_width, anti_alias);
    if (pGlyphBitmap) {
      CFX_GlyphBitmap* pResult = pGlyphBitmap.get();

      SizeGlyphCache cache;
      cache[glyph_index] = std::move(pGlyphBitmap);

      m_SizeMap[FaceGlyphsKey] = std::move(cache);
      return pResult;
    }
  }
  GenKey(&keygen, pFont, matrix, dest_width, anti_alias, /*bNative=*/false);
  ByteString FaceGlyphsKey2(keygen.key_, keygen.key_len_);
  text_options->native_text = false;
  return LookUpGlyphBitmap(pFont, matrix, FaceGlyphsKey2, glyph_index,
                           bFontStyle, dest_width, anti_alias);
#endif  // BUILDFLAG(IS_APPLE)
}

int CFX_GlyphCache::GetGlyphWidth(const CFX_Font* font,
                                  uint32_t glyph_index,
                                  int dest_width,
                                  int weight) {
  const WidthMapKey key = std::make_tuple(glyph_index, dest_width, weight);
  auto it = m_WidthMap.find(key);
  if (it != m_WidthMap.end()) {
    return it->second;
  }

  m_WidthMap[key] = font->GetGlyphWidthImpl(glyph_index, dest_width, weight);
  return m_WidthMap[key];
}

#if defined(_SKIA_SUPPORT_)
CFX_TypeFace* CFX_GlyphCache::GetDeviceCache(const CFX_Font* pFont) {
  if (!m_pTypeface) {
    pdfium::span<const uint8_t> span = pFont->GetFontSpan();
    m_pTypeface = SkTypeface::MakeFromStream(
        std::make_unique<SkMemoryStream>(span.data(), span.size()));
  }
#if BUILDFLAG(IS_WIN)
  if (!m_pTypeface) {
    sk_sp<SkFontMgr> customMgr(SkFontMgr_New_Custom_Empty());
    pdfium::span<const uint8_t> span = pFont->GetFontSpan();
    m_pTypeface = customMgr->makeFromStream(
        std::make_unique<SkMemoryStream>(span.data(), span.size()));
  }
#endif  // BUILDFLAG(IS_WIN)
  return m_pTypeface.get();
}
#endif  // defined(_SKIA_SUPPORT_)

CFX_GlyphBitmap* CFX_GlyphCache::LookUpGlyphBitmap(
    const CFX_Font* pFont,
    const CFX_Matrix& matrix,
    const ByteString& FaceGlyphsKey,
    uint32_t glyph_index,
    bool bFontStyle,
    int dest_width,
    int anti_alias) {
  SizeGlyphCache* pSizeCache;
  auto it = m_SizeMap.find(FaceGlyphsKey);
  if (it == m_SizeMap.end()) {
    m_SizeMap[FaceGlyphsKey] = SizeGlyphCache();
    pSizeCache = &(m_SizeMap[FaceGlyphsKey]);
  } else {
    pSizeCache = &(it->second);
  }

  auto it2 = pSizeCache->find(glyph_index);
  if (it2 != pSizeCache->end())
    return it2->second.get();

  std::unique_ptr<CFX_GlyphBitmap> pGlyphBitmap = RenderGlyph(
      pFont, glyph_index, bFontStyle, matrix, dest_width, anti_alias);
  CFX_GlyphBitmap* pResult = pGlyphBitmap.get();
  (*pSizeCache)[glyph_index] = std::move(pGlyphBitmap);
  return pResult;
}
