// Copyright 2014 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

#if defined(UNSAFE_BUFFERS_BUILD)
// TODO(crbug.com/pdfium/2153): resolve buffer safety issues.
#pragma allow_unsafe_buffers
#endif

#include "core/fpdfapi/page/cpdf_docpagedata.h"

#include <algorithm>
#include <memory>
#include <set>
#include <utility>
#include <vector>

#include "build/build_config.h"
#include "constants/font_encodings.h"
#include "core/fpdfapi/font/cpdf_fontglobals.h"
#include "core/fpdfapi/font/cpdf_type1font.h"
#include "core/fpdfapi/page/cpdf_form.h"
#include "core/fpdfapi/page/cpdf_iccprofile.h"
#include "core/fpdfapi/page/cpdf_image.h"
#include "core/fpdfapi/page/cpdf_pattern.h"
#include "core/fpdfapi/page/cpdf_shadingpattern.h"
#include "core/fpdfapi/page/cpdf_tilingpattern.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_name.h"
#include "core/fpdfapi/parser/cpdf_number.h"
#include "core/fpdfapi/parser/cpdf_reference.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fpdfapi/parser/cpdf_string.h"
#include "core/fxcodec/icc/icc_transform.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/containers/contains.h"
#include "core/fxcrt/fixed_size_data_vector.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/scoped_set_insertion.h"
#include "core/fxge/cfx_font.h"
#include "core/fxge/cfx_fontmapper.h"
#include "core/fxge/cfx_substfont.h"
#include "core/fxge/cfx_unicodeencoding.h"
#include "core/fxge/fx_font.h"

namespace {

void InsertWidthArrayImpl(std::vector<int> widths, CPDF_Array* pWidthArray) {
  size_t i;
  for (i = 1; i < widths.size(); i++) {
    if (widths[i] != widths[0])
      break;
  }
  if (i == widths.size()) {
    int first = pWidthArray->GetIntegerAt(pWidthArray->size() - 1);
    pWidthArray->AppendNew<CPDF_Number>(first +
                                        static_cast<int>(widths.size()) - 1);
    pWidthArray->AppendNew<CPDF_Number>(widths[0]);
    return;
  }
  auto pWidthArray1 = pWidthArray->AppendNew<CPDF_Array>();
  for (int w : widths)
    pWidthArray1->AppendNew<CPDF_Number>(w);
}

#if BUILDFLAG(IS_WIN)
void InsertWidthArray(HDC hDC, int start, int end, CPDF_Array* pWidthArray) {
  std::vector<int> widths(end - start + 1);
  GetCharWidth(hDC, start, end, widths.data());
  InsertWidthArrayImpl(std::move(widths), pWidthArray);
}

ByteString GetPSNameFromTT(HDC hDC) {
  ByteString result;
  DWORD size = ::GetFontData(hDC, 'eman', 0, nullptr, 0);
  if (size != GDI_ERROR) {
    auto buffer = FixedSizeDataVector<BYTE>::Uninit(size);
    ::GetFontData(hDC, 'eman', 0, buffer.span().data(), buffer.size());
    result = GetNameFromTT(buffer, 6);
  }
  return result;
}
#endif  // BUILDFLAG(IS_WIN)

void InsertWidthArray1(CFX_Font* pFont,
                       CFX_UnicodeEncoding* pEncoding,
                       wchar_t start,
                       wchar_t end,
                       CPDF_Array* pWidthArray) {
  std::vector<int> widths(end - start + 1);
  for (size_t i = 0; i < widths.size(); ++i) {
    int glyph_index = pEncoding->GlyphFromCharCode(start + i);
    widths[i] = pFont->GetGlyphWidth(glyph_index);
  }
  InsertWidthArrayImpl(std::move(widths), pWidthArray);
}

int CalculateFlags(bool bold,
                   bool italic,
                   bool fixedPitch,
                   bool serif,
                   bool script,
                   bool symbolic) {
  int flags = 0;
  if (bold)
    flags |= FXFONT_FORCE_BOLD;
  if (italic)
    flags |= FXFONT_ITALIC;
  if (fixedPitch)
    flags |= FXFONT_FIXED_PITCH;
  if (serif)
    flags |= FXFONT_SERIF;
  if (script)
    flags |= FXFONT_SCRIPT;
  if (symbolic)
    flags |= FXFONT_SYMBOLIC;
  else
    flags |= FXFONT_NONSYMBOLIC;
  return flags;
}

void ProcessNonbCJK(RetainPtr<CPDF_Dictionary> pBaseDict,
                    bool bold,
                    bool italic,
                    ByteString basefont,
                    RetainPtr<CPDF_Array> pWidths) {
  if (bold && italic)
    basefont += ",BoldItalic";
  else if (bold)
    basefont += ",Bold";
  else if (italic)
    basefont += ",Italic";
  pBaseDict->SetNewFor<CPDF_Name>("Subtype", "TrueType");
  pBaseDict->SetNewFor<CPDF_Name>("BaseFont", basefont);
  pBaseDict->SetNewFor<CPDF_Number>("FirstChar", 32);
  pBaseDict->SetNewFor<CPDF_Number>("LastChar", 255);
  pBaseDict->SetFor("Widths", pWidths);
}

RetainPtr<CPDF_Dictionary> CalculateFontDesc(CPDF_Document* pDoc,
                                             ByteString basefont,
                                             int flags,
                                             int italicangle,
                                             int ascend,
                                             int descend,
                                             RetainPtr<CPDF_Array> bbox,
                                             int32_t stemV) {
  auto pFontDesc = pDoc->New<CPDF_Dictionary>();
  pFontDesc->SetNewFor<CPDF_Name>("Type", "FontDescriptor");
  pFontDesc->SetNewFor<CPDF_Name>("FontName", basefont);
  pFontDesc->SetNewFor<CPDF_Number>("Flags", flags);
  pFontDesc->SetFor("FontBBox", bbox);
  pFontDesc->SetNewFor<CPDF_Number>("ItalicAngle", italicangle);
  pFontDesc->SetNewFor<CPDF_Number>("Ascent", ascend);
  pFontDesc->SetNewFor<CPDF_Number>("Descent", descend);
  pFontDesc->SetNewFor<CPDF_Number>("StemV", stemV);
  return pFontDesc;
}

}  // namespace

// static
CPDF_DocPageData* CPDF_DocPageData::FromDocument(const CPDF_Document* pDoc) {
  return static_cast<CPDF_DocPageData*>(pDoc->GetPageData());
}

CPDF_DocPageData::CPDF_DocPageData() = default;

CPDF_DocPageData::~CPDF_DocPageData() {
  for (auto& it : m_FontMap) {
    if (it.second)
      it.second->WillBeDestroyed();
  }
}

CPDF_DocPageData::HashIccProfileKey::HashIccProfileKey(ByteString digest,
                                                       uint32_t components)
    : digest(std::move(digest)), components(components) {}

CPDF_DocPageData::HashIccProfileKey::~HashIccProfileKey() = default;

bool CPDF_DocPageData::HashIccProfileKey::operator<(
    const HashIccProfileKey& other) const {
  if (components == other.components) {
    return digest < other.digest;
  }
  return components < other.components;
}

void CPDF_DocPageData::ClearStockFont() {
  CPDF_FontGlobals::GetInstance()->Clear(GetDocument());
}

RetainPtr<CPDF_Font> CPDF_DocPageData::GetFont(
    RetainPtr<CPDF_Dictionary> pFontDict) {
  if (!pFontDict)
    return nullptr;

  auto it = m_FontMap.find(pFontDict);
  if (it != m_FontMap.end() && it->second)
    return pdfium::WrapRetain(it->second.Get());

  RetainPtr<CPDF_Font> pFont =
      CPDF_Font::Create(GetDocument(), pFontDict, this);
  if (!pFont)
    return nullptr;

  m_FontMap[std::move(pFontDict)].Reset(pFont.Get());
  return pFont;
}

RetainPtr<CPDF_Font> CPDF_DocPageData::GetStandardFont(
    const ByteString& fontName,
    const CPDF_FontEncoding* pEncoding) {
  if (fontName.IsEmpty())
    return nullptr;

  for (auto& it : m_FontMap) {
    CPDF_Font* pFont = it.second.Get();
    if (!pFont)
      continue;
    if (pFont->GetBaseFontName() != fontName)
      continue;
    if (pFont->IsEmbedded())
      continue;
    if (!pFont->IsType1Font())
      continue;
    if (pFont->GetFontDict()->KeyExist("Widths"))
      continue;

    CPDF_Type1Font* pT1Font = pFont->AsType1Font();
    if (pEncoding && !pT1Font->GetEncoding()->IsIdentical(pEncoding))
      continue;

    return pdfium::WrapRetain(pFont);
  }

  auto pDict = GetDocument()->NewIndirect<CPDF_Dictionary>();
  pDict->SetNewFor<CPDF_Name>("Type", "Font");
  pDict->SetNewFor<CPDF_Name>("Subtype", "Type1");
  pDict->SetNewFor<CPDF_Name>("BaseFont", fontName);
  if (pEncoding) {
    pDict->SetFor("Encoding",
                  pEncoding->Realize(GetDocument()->GetByteStringPool()));
  }

  // Note: NULL FormFactoryIface OK since known Type1 font from above.
  RetainPtr<CPDF_Font> pFont = CPDF_Font::Create(GetDocument(), pDict, nullptr);
  if (!pFont)
    return nullptr;

  m_FontMap[std::move(pDict)].Reset(pFont.Get());
  return pFont;
}

RetainPtr<CPDF_ColorSpace> CPDF_DocPageData::GetColorSpace(
    const CPDF_Object* pCSObj,
    const CPDF_Dictionary* pResources) {
  std::set<const CPDF_Object*> visited;
  return GetColorSpaceGuarded(pCSObj, pResources, &visited);
}

RetainPtr<CPDF_ColorSpace> CPDF_DocPageData::GetColorSpaceGuarded(
    const CPDF_Object* pCSObj,
    const CPDF_Dictionary* pResources,
    std::set<const CPDF_Object*>* pVisited) {
  std::set<const CPDF_Object*> visitedLocal;
  return GetColorSpaceInternal(pCSObj, pResources, pVisited, &visitedLocal);
}

RetainPtr<CPDF_ColorSpace> CPDF_DocPageData::GetColorSpaceInternal(
    const CPDF_Object* pCSObj,
    const CPDF_Dictionary* pResources,
    std::set<const CPDF_Object*>* pVisited,
    std::set<const CPDF_Object*>* pVisitedInternal) {
  if (!pCSObj)
    return nullptr;

  if (pdfium::Contains(*pVisitedInternal, pCSObj))
    return nullptr;

  ScopedSetInsertion<const CPDF_Object*> insertion(pVisitedInternal, pCSObj);

  if (pCSObj->IsName()) {
    ByteString name = pCSObj->GetString();
    RetainPtr<CPDF_ColorSpace> pCS = CPDF_ColorSpace::GetStockCSForName(name);
    if (!pCS && pResources) {
      RetainPtr<const CPDF_Dictionary> pList =
          pResources->GetDictFor("ColorSpace");
      if (pList) {
        return GetColorSpaceInternal(pList->GetDirectObjectFor(name).Get(),
                                     nullptr, pVisited, pVisitedInternal);
      }
    }
    if (!pCS || !pResources)
      return pCS;

    RetainPtr<const CPDF_Dictionary> pColorSpaces =
        pResources->GetDictFor("ColorSpace");
    if (!pColorSpaces)
      return pCS;

    RetainPtr<const CPDF_Object> pDefaultCS;
    switch (pCS->GetFamily()) {
      case CPDF_ColorSpace::Family::kDeviceRGB:
        pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultRGB");
        break;
      case CPDF_ColorSpace::Family::kDeviceGray:
        pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultGray");
        break;
      case CPDF_ColorSpace::Family::kDeviceCMYK:
        pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultCMYK");
        break;
      default:
        break;
    }
    if (!pDefaultCS)
      return pCS;

    return GetColorSpaceInternal(pDefaultCS.Get(), nullptr, pVisited,
                                 pVisitedInternal);
  }

  RetainPtr<const CPDF_Array> pArray(pCSObj->AsArray());
  if (!pArray || pArray->IsEmpty())
    return nullptr;

  if (pArray->size() == 1) {
    return GetColorSpaceInternal(pArray->GetDirectObjectAt(0).Get(), pResources,
                                 pVisited, pVisitedInternal);
  }

  auto it = m_ColorSpaceMap.find(pArray);
  if (it != m_ColorSpaceMap.end() && it->second)
    return pdfium::WrapRetain(it->second.Get());

  RetainPtr<CPDF_ColorSpace> pCS =
      CPDF_ColorSpace::Load(GetDocument(), pArray.Get(), pVisited);
  if (!pCS)
    return nullptr;

  m_ColorSpaceMap[std::move(pArray)].Reset(pCS.Get());
  return pCS;
}

RetainPtr<CPDF_Pattern> CPDF_DocPageData::GetPattern(
    RetainPtr<CPDF_Object> pPatternObj,
    const CFX_Matrix& matrix) {
  CHECK(pPatternObj->IsDictionary() || pPatternObj->IsStream());

  auto it = m_PatternMap.find(pPatternObj);
  if (it != m_PatternMap.end() && it->second)
    return pdfium::WrapRetain(it->second.Get());

  RetainPtr<CPDF_Pattern> pattern;
  switch (pPatternObj->GetDict()->GetIntegerFor("PatternType")) {
    case CPDF_Pattern::kTiling:
      pattern = pdfium::MakeRetain<CPDF_TilingPattern>(GetDocument(),
                                                       pPatternObj, matrix);
      break;
    case CPDF_Pattern::kShading:
      pattern = pdfium::MakeRetain<CPDF_ShadingPattern>(
          GetDocument(), pPatternObj, false, matrix);
      break;
    default:
      return nullptr;
  }
  m_PatternMap[pPatternObj].Reset(pattern.Get());
  return pattern;
}

RetainPtr<CPDF_ShadingPattern> CPDF_DocPageData::GetShading(
    RetainPtr<CPDF_Object> pPatternObj,
    const CFX_Matrix& matrix) {
  CHECK(pPatternObj->IsDictionary() || pPatternObj->IsStream());

  auto it = m_PatternMap.find(pPatternObj);
  if (it != m_PatternMap.end() && it->second)
    return pdfium::WrapRetain(it->second->AsShadingPattern());

  auto pPattern = pdfium::MakeRetain<CPDF_ShadingPattern>(
      GetDocument(), pPatternObj, true, matrix);
  m_PatternMap[pPatternObj].Reset(pPattern.Get());
  return pPattern;
}

RetainPtr<CPDF_Image> CPDF_DocPageData::GetImage(uint32_t dwStreamObjNum) {
  DCHECK(dwStreamObjNum);
  auto it = m_ImageMap.find(dwStreamObjNum);
  if (it != m_ImageMap.end())
    return it->second;

  auto pImage = pdfium::MakeRetain<CPDF_Image>(GetDocument(), dwStreamObjNum);
  m_ImageMap[dwStreamObjNum] = pImage;
  return pImage;
}

void CPDF_DocPageData::MaybePurgeImage(uint32_t dwStreamObjNum) {
  DCHECK(dwStreamObjNum);
  auto it = m_ImageMap.find(dwStreamObjNum);
  if (it != m_ImageMap.end() && it->second->HasOneRef())
    m_ImageMap.erase(it);
}

RetainPtr<CPDF_IccProfile> CPDF_DocPageData::GetIccProfile(
    RetainPtr<const CPDF_Stream> pProfileStream) {
  CHECK(pProfileStream);

  auto it = m_IccProfileMap.find(pProfileStream);
  if (it != m_IccProfileMap.end()) {
    return it->second;
  }

  auto pAccessor = pdfium::MakeRetain<CPDF_StreamAcc>(pProfileStream);
  pAccessor->LoadAllDataFiltered();

  // This should not fail, as the caller should have checked this already.
  const int expected_components = pProfileStream->GetDict()->GetIntegerFor("N");
  CHECK(fxcodec::IccTransform::IsValidIccComponents(expected_components));

  // Since CPDF_IccProfile can behave differently depending on
  // `expected_components`, `hash_profile_key` needs to take that into
  // consideration, in addition to the digest value.
  const HashIccProfileKey hash_profile_key(pAccessor->ComputeDigest(),
                                           expected_components);
  auto hash_it = m_HashIccProfileMap.find(hash_profile_key);
  if (hash_it != m_HashIccProfileMap.end()) {
    auto it_copied_stream = m_IccProfileMap.find(hash_it->second);
    if (it_copied_stream != m_IccProfileMap.end()) {
      return it_copied_stream->second;
    }
  }
  auto pProfile =
      pdfium::MakeRetain<CPDF_IccProfile>(pAccessor, expected_components);
  m_IccProfileMap[pProfileStream] = pProfile;
  m_HashIccProfileMap[hash_profile_key] = std::move(pProfileStream);
  return pProfile;
}

RetainPtr<CPDF_StreamAcc> CPDF_DocPageData::GetFontFileStreamAcc(
    RetainPtr<const CPDF_Stream> pFontStream) {
  DCHECK(pFontStream);
  auto it = m_FontFileMap.find(pFontStream);
  if (it != m_FontFileMap.end())
    return it->second;

  RetainPtr<const CPDF_Dictionary> pFontDict = pFontStream->GetDict();
  int32_t len1 = pFontDict->GetIntegerFor("Length1");
  int32_t len2 = pFontDict->GetIntegerFor("Length2");
  int32_t len3 = pFontDict->GetIntegerFor("Length3");
  uint32_t org_size = 0;
  if (len1 >= 0 && len2 >= 0 && len3 >= 0) {
    FX_SAFE_UINT32 safe_org_size = len1;
    safe_org_size += len2;
    safe_org_size += len3;
    org_size = safe_org_size.ValueOrDefault(0);
  }

  auto pFontAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pFontStream);
  pFontAcc->LoadAllDataFilteredWithEstimatedSize(org_size);
  m_FontFileMap[std::move(pFontStream)] = pFontAcc;
  return pFontAcc;
}

void CPDF_DocPageData::MaybePurgeFontFileStreamAcc(
    RetainPtr<CPDF_StreamAcc>&& pStreamAcc) {
  if (!pStreamAcc)
    return;

  RetainPtr<const CPDF_Stream> pFontStream = pStreamAcc->GetStream();
  if (!pFontStream)
    return;

  pStreamAcc.Reset();  // Drop moved caller's reference.
  auto it = m_FontFileMap.find(std::move(pFontStream));
  if (it != m_FontFileMap.end() && it->second->HasOneRef())
    m_FontFileMap.erase(it);
}

std::unique_ptr<CPDF_Font::FormIface> CPDF_DocPageData::CreateForm(
    CPDF_Document* pDocument,
    RetainPtr<CPDF_Dictionary> pPageResources,
    RetainPtr<CPDF_Stream> pFormStream) {
  return std::make_unique<CPDF_Form>(pDocument, std::move(pPageResources),
                                     std::move(pFormStream));
}

RetainPtr<CPDF_Font> CPDF_DocPageData::AddStandardFont(
    const ByteString& fontName,
    const CPDF_FontEncoding* pEncoding) {
  ByteString mutable_name(fontName);
  std::optional<CFX_FontMapper::StandardFont> font_id =
      CFX_FontMapper::GetStandardFontName(&mutable_name);
  if (!font_id.has_value())
    return nullptr;
  return GetStandardFont(mutable_name, pEncoding);
}

RetainPtr<CPDF_Font> CPDF_DocPageData::AddFont(std::unique_ptr<CFX_Font> pFont,
                                               FX_Charset charset) {
  if (!pFont)
    return nullptr;

  const bool bCJK = FX_CharSetIsCJK(charset);
  ByteString basefont = pFont->GetFamilyName();
  basefont.Replace(" ", "");
  int flags =
      CalculateFlags(pFont->IsBold(), pFont->IsItalic(), pFont->IsFixedWidth(),
                     false, false, charset == FX_Charset::kSymbol);

  auto pBaseDict = GetDocument()->NewIndirect<CPDF_Dictionary>();
  pBaseDict->SetNewFor<CPDF_Name>("Type", "Font");

  auto pEncoding = std::make_unique<CFX_UnicodeEncoding>(pFont.get());
  RetainPtr<CPDF_Dictionary> pFontDict = pBaseDict;
  if (!bCJK) {
    auto pWidths = pdfium::MakeRetain<CPDF_Array>();
    for (int charcode = 32; charcode < 128; charcode++) {
      int glyph_index = pEncoding->GlyphFromCharCode(charcode);
      int char_width = pFont->GetGlyphWidth(glyph_index);
      pWidths->AppendNew<CPDF_Number>(char_width);
    }
    if (charset == FX_Charset::kANSI || charset == FX_Charset::kDefault ||
        charset == FX_Charset::kSymbol) {
      pBaseDict->SetNewFor<CPDF_Name>("Encoding",
                                      pdfium::font_encodings::kWinAnsiEncoding);
      for (int charcode = 128; charcode <= 255; charcode++) {
        int glyph_index = pEncoding->GlyphFromCharCode(charcode);
        int char_width = pFont->GetGlyphWidth(glyph_index);
        pWidths->AppendNew<CPDF_Number>(char_width);
      }
    } else {
      size_t i = CalculateEncodingDict(charset, pBaseDict.Get());
      if (i < std::size(kFX_CharsetUnicodes)) {
        const uint16_t* pUnicodes = kFX_CharsetUnicodes[i].m_pUnicodes;
        for (int j = 0; j < 128; j++) {
          int glyph_index = pEncoding->GlyphFromCharCode(pUnicodes[j]);
          int char_width = pFont->GetGlyphWidth(glyph_index);
          pWidths->AppendNew<CPDF_Number>(char_width);
        }
      }
    }
    ProcessNonbCJK(pBaseDict, pFont->IsBold(), pFont->IsItalic(), basefont,
                   std::move(pWidths));
  } else {
    pFontDict = ProcessbCJK(
        pBaseDict, charset, basefont,
        [&pFont, &pEncoding](wchar_t start, wchar_t end, CPDF_Array* widthArr) {
          InsertWidthArray1(pFont.get(), pEncoding.get(), start, end, widthArr);
        });
  }
  int italicangle = pFont->GetSubstFontItalicAngle();
  FX_RECT bbox = pFont->GetBBox().value_or(FX_RECT());
  auto pBBox = pdfium::MakeRetain<CPDF_Array>();
  pBBox->AppendNew<CPDF_Number>(bbox.left);
  pBBox->AppendNew<CPDF_Number>(bbox.bottom);
  pBBox->AppendNew<CPDF_Number>(bbox.right);
  pBBox->AppendNew<CPDF_Number>(bbox.top);
  int32_t nStemV = 0;
  if (pFont->GetSubstFont()) {
    nStemV = pFont->GetSubstFont()->m_Weight / 5;
  } else {
    static const char stem_chars[] = {'i', 'I', '!', '1'};
    const size_t count = std::size(stem_chars);
    uint32_t glyph = pEncoding->GlyphFromCharCode(stem_chars[0]);
    nStemV = pFont->GetGlyphWidth(glyph);
    for (size_t i = 1; i < count; i++) {
      glyph = pEncoding->GlyphFromCharCode(stem_chars[i]);
      int width = pFont->GetGlyphWidth(glyph);
      if (width > 0 && width < nStemV)
        nStemV = width;
    }
  }
  RetainPtr<CPDF_Dictionary> pFontDesc = CalculateFontDesc(
      GetDocument(), basefont, flags, italicangle, pFont->GetAscent(),
      pFont->GetDescent(), std::move(pBBox), nStemV);
  uint32_t new_objnum = GetDocument()->AddIndirectObject(std::move(pFontDesc));
  pFontDict->SetNewFor<CPDF_Reference>("FontDescriptor", GetDocument(),
                                       new_objnum);
  return GetFont(pBaseDict);
}

#if BUILDFLAG(IS_WIN)
RetainPtr<CPDF_Font> CPDF_DocPageData::AddWindowsFont(LOGFONTA* pLogFont) {
  pLogFont->lfHeight = -1000;
  pLogFont->lfWidth = 0;
  HGDIOBJ hFont = CreateFontIndirectA(pLogFont);
  HDC hDC = CreateCompatibleDC(nullptr);
  hFont = SelectObject(hDC, hFont);
  int tm_size = GetOutlineTextMetrics(hDC, 0, nullptr);
  if (tm_size == 0) {
    hFont = SelectObject(hDC, hFont);
    DeleteObject(hFont);
    DeleteDC(hDC);
    return nullptr;
  }

  LPBYTE tm_buf = FX_Alloc(BYTE, tm_size);
  OUTLINETEXTMETRIC* ptm = reinterpret_cast<OUTLINETEXTMETRIC*>(tm_buf);
  GetOutlineTextMetrics(hDC, tm_size, ptm);
  int flags = CalculateFlags(
      false, pLogFont->lfItalic != 0,
      (pLogFont->lfPitchAndFamily & 3) == FIXED_PITCH,
      (pLogFont->lfPitchAndFamily & 0xf8) == FF_ROMAN,
      (pLogFont->lfPitchAndFamily & 0xf8) == FF_SCRIPT,
      pLogFont->lfCharSet == static_cast<int>(FX_Charset::kSymbol));

  const FX_Charset eCharset = FX_GetCharsetFromInt(pLogFont->lfCharSet);
  const bool bCJK = FX_CharSetIsCJK(eCharset);
  ByteString basefont;
  if (bCJK)
    basefont = GetPSNameFromTT(hDC);

  if (basefont.IsEmpty())
    basefont = pLogFont->lfFaceName;

  int italicangle = ptm->otmItalicAngle / 10;
  int ascend = ptm->otmrcFontBox.top;
  int descend = ptm->otmrcFontBox.bottom;
  int capheight = ptm->otmsCapEmHeight;
  int bbox[4] = {ptm->otmrcFontBox.left, ptm->otmrcFontBox.bottom,
                 ptm->otmrcFontBox.right, ptm->otmrcFontBox.top};
  FX_Free(tm_buf);
  basefont.Replace(" ", "");
  auto pBaseDict = GetDocument()->NewIndirect<CPDF_Dictionary>();
  pBaseDict->SetNewFor<CPDF_Name>("Type", "Font");
  RetainPtr<CPDF_Dictionary> pFontDict = pBaseDict;
  if (!bCJK) {
    if (eCharset == FX_Charset::kANSI || eCharset == FX_Charset::kDefault ||
        eCharset == FX_Charset::kSymbol) {
      pBaseDict->SetNewFor<CPDF_Name>("Encoding",
                                      pdfium::font_encodings::kWinAnsiEncoding);
    } else {
      CalculateEncodingDict(eCharset, pBaseDict.Get());
    }
    int char_widths[224];
    GetCharWidth(hDC, 32, 255, char_widths);
    auto pWidths = pdfium::MakeRetain<CPDF_Array>();
    for (size_t i = 0; i < 224; i++)
      pWidths->AppendNew<CPDF_Number>(char_widths[i]);
    ProcessNonbCJK(pBaseDict, pLogFont->lfWeight > FW_MEDIUM,
                   pLogFont->lfItalic != 0, basefont, std::move(pWidths));
  } else {
    pFontDict =
        ProcessbCJK(pBaseDict, eCharset, basefont,
                    [&hDC](wchar_t start, wchar_t end, CPDF_Array* widthArr) {
                      InsertWidthArray(hDC, start, end, widthArr);
                    });
  }
  auto pBBox = pdfium::MakeRetain<CPDF_Array>();
  for (int i = 0; i < 4; i++)
    pBBox->AppendNew<CPDF_Number>(bbox[i]);
  RetainPtr<CPDF_Dictionary> pFontDesc =
      CalculateFontDesc(GetDocument(), basefont, flags, italicangle, ascend,
                        descend, std::move(pBBox), pLogFont->lfWeight / 5);
  pFontDesc->SetNewFor<CPDF_Number>("CapHeight", capheight);
  GetDocument()->AddIndirectObject(pFontDesc);
  pFontDict->SetFor("FontDescriptor", pFontDesc->MakeReference(GetDocument()));
  hFont = SelectObject(hDC, hFont);
  DeleteObject(hFont);
  DeleteDC(hDC);
  return GetFont(std::move(pBaseDict));
}
#endif  //  BUILDFLAG(IS_WIN)

size_t CPDF_DocPageData::CalculateEncodingDict(FX_Charset charset,
                                               CPDF_Dictionary* pBaseDict) {
  size_t i;
  for (i = 0; i < std::size(kFX_CharsetUnicodes); ++i) {
    if (kFX_CharsetUnicodes[i].m_Charset == charset)
      break;
  }
  if (i == std::size(kFX_CharsetUnicodes))
    return i;

  auto pEncodingDict = GetDocument()->NewIndirect<CPDF_Dictionary>();
  pEncodingDict->SetNewFor<CPDF_Name>("BaseEncoding",
                                      pdfium::font_encodings::kWinAnsiEncoding);

  auto pArray = pEncodingDict->SetNewFor<CPDF_Array>("Differences");
  pArray->AppendNew<CPDF_Number>(128);

  const uint16_t* pUnicodes = kFX_CharsetUnicodes[i].m_pUnicodes;
  for (int j = 0; j < 128; j++) {
    ByteString name = AdobeNameFromUnicode(pUnicodes[j]);
    pArray->AppendNew<CPDF_Name>(name.IsEmpty() ? ".notdef" : name);
  }
  pBaseDict->SetNewFor<CPDF_Reference>("Encoding", GetDocument(),
                                       pEncodingDict->GetObjNum());
  return i;
}

RetainPtr<CPDF_Dictionary> CPDF_DocPageData::ProcessbCJK(
    RetainPtr<CPDF_Dictionary> pBaseDict,
    FX_Charset charset,
    ByteString basefont,
    std::function<void(wchar_t, wchar_t, CPDF_Array*)> Insert) {
  auto pFontDict = GetDocument()->NewIndirect<CPDF_Dictionary>();
  ByteString cmap;
  ByteString ordering;
  int supplement = 0;
  auto pWidthArray = pFontDict->SetNewFor<CPDF_Array>("W");
  switch (charset) {
    case FX_Charset::kChineseTraditional:
      cmap = "ETenms-B5-H";
      ordering = "CNS1";
      supplement = 4;
      pWidthArray->AppendNew<CPDF_Number>(1);
      Insert(0x20, 0x7e, pWidthArray.Get());
      break;
    case FX_Charset::kChineseSimplified:
      cmap = "GBK-EUC-H";
      ordering = "GB1";
      supplement = 2;
      pWidthArray->AppendNew<CPDF_Number>(7716);
      Insert(0x20, 0x20, pWidthArray.Get());
      pWidthArray->AppendNew<CPDF_Number>(814);
      Insert(0x21, 0x7e, pWidthArray.Get());
      break;
    case FX_Charset::kHangul:
      cmap = "KSCms-UHC-H";
      ordering = "Korea1";
      supplement = 2;
      pWidthArray->AppendNew<CPDF_Number>(1);
      Insert(0x20, 0x7e, pWidthArray.Get());
      break;
    case FX_Charset::kShiftJIS:
      cmap = "90ms-RKSJ-H";
      ordering = "Japan1";
      supplement = 5;
      pWidthArray->AppendNew<CPDF_Number>(231);
      Insert(0x20, 0x7d, pWidthArray.Get());
      pWidthArray->AppendNew<CPDF_Number>(326);
      Insert(0xa0, 0xa0, pWidthArray.Get());
      pWidthArray->AppendNew<CPDF_Number>(327);
      Insert(0xa1, 0xdf, pWidthArray.Get());
      pWidthArray->AppendNew<CPDF_Number>(631);
      Insert(0x7e, 0x7e, pWidthArray.Get());
      break;
    default:
      break;
  }
  pBaseDict->SetNewFor<CPDF_Name>("Subtype", "Type0");
  pBaseDict->SetNewFor<CPDF_Name>("BaseFont", basefont);
  pBaseDict->SetNewFor<CPDF_Name>("Encoding", cmap);
  pFontDict->SetNewFor<CPDF_Name>("Type", "Font");
  pFontDict->SetNewFor<CPDF_Name>("Subtype", "CIDFontType2");
  pFontDict->SetNewFor<CPDF_Name>("BaseFont", basefont);

  auto pCIDSysInfo = pFontDict->SetNewFor<CPDF_Dictionary>("CIDSystemInfo");
  pCIDSysInfo->SetNewFor<CPDF_String>("Registry", "Adobe", false);
  pCIDSysInfo->SetNewFor<CPDF_String>("Ordering", ordering, false);
  pCIDSysInfo->SetNewFor<CPDF_Number>("Supplement", supplement);

  auto pArray = pBaseDict->SetNewFor<CPDF_Array>("DescendantFonts");
  pArray->AppendNew<CPDF_Reference>(GetDocument(), pFontDict->GetObjNum());
  return pFontDict;
}
