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

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

#include <algorithm>
#include <array>
#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/fxcrt/span.h"
#include "core/fxge/cfx_charmap_resolver.h"
#include "core/fxge/cfx_font.h"
#include "core/fxge/cfx_fontmapper.h"
#include "core/fxge/cfx_substfont.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* font,
                       CFX_CharmapResolver* charmap_resolver,
                       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 = charmap_resolver->GlyphFromCharCode(start + i);
    widths[i] = font->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 |= pdfium::kFontStyleForceBold;
  }
  if (italic) {
    flags |= pdfium::kFontStyleItalic;
  }
  if (fixedPitch) {
    flags |= pdfium::kFontStyleFixedPitch;
  }
  if (serif) {
    flags |= pdfium::kFontStyleSerif;
  }
  if (script) {
    flags |= pdfium::kFontStyleScript;
  }
  if (symbolic) {
    flags |= pdfium::kFontStyleSymbolic;
  } else {
    flags |= pdfium::kFontStyleNonSymbolic;
  }
  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* doc,
                                             ByteString basefont,
                                             int flags,
                                             int italicangle,
                                             int ascend,
                                             int descend,
                                             RetainPtr<CPDF_Array> bbox,
                                             int32_t stemV) {
  auto font_desc = doc->New<CPDF_Dictionary>();
  font_desc->SetNewFor<CPDF_Name>("Type", "FontDescriptor");
  font_desc->SetNewFor<CPDF_Name>("FontName", basefont);
  font_desc->SetNewFor<CPDF_Number>("Flags", flags);
  font_desc->SetFor("FontBBox", bbox);
  font_desc->SetNewFor<CPDF_Number>("ItalicAngle", italicangle);
  font_desc->SetNewFor<CPDF_Number>("Ascent", ascend);
  font_desc->SetNewFor<CPDF_Number>("Descent", descend);
  font_desc->SetNewFor<CPDF_Number>("StemV", stemV);
  return font_desc;
}

}  // namespace

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

CPDF_DocPageData::CPDF_DocPageData() = default;

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

CPDF_DocPageData::HashIccProfileKey::HashIccProfileKey(
    DataVector<uint8_t> digest,
    uint32_t components)
    : digest(std::move(digest)), components(components) {}

CPDF_DocPageData::HashIccProfileKey::HashIccProfileKey(
    const HashIccProfileKey& that) = default;

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> font_dict) {
  if (!font_dict) {
    return nullptr;
  }

  auto it = font_map_.find(font_dict);
  if (it != font_map_.end() && it->second) {
    return pdfium::WrapRetain(it->second.Get());
  }

  RetainPtr<CPDF_Font> font = CPDF_Font::Create(GetDocument(), font_dict, this);
  if (!font) {
    return nullptr;
  }

  font_map_[std::move(font_dict)].Reset(font.Get());
  return font;
}

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

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

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

    return pdfium::WrapRetain(font);
  }

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

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

  font_map_[std::move(dict)].Reset(font.Get());
  return font;
}

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 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.AsStringView()).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 = color_space_map_.find(pArray);
  if (it != color_space_map_.end() && it->second) {
    return pdfium::WrapRetain(it->second.Get());
  }

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

  color_space_map_[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 = pattern_map_.find(pPatternObj);
  if (it != pattern_map_.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;
  }
  pattern_map_[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 = pattern_map_.find(pPatternObj);
  if (it != pattern_map_.end() && it->second) {
    return pdfium::WrapRetain(it->second->AsShadingPattern());
  }

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

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

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

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

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

  auto it = icc_profile_map_.find(pProfileStream);
  if (it != icc_profile_map_.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 = hash_icc_profile_map_.find(hash_profile_key);
  if (hash_it != hash_icc_profile_map_.end()) {
    auto it_copied_stream = icc_profile_map_.find(hash_it->second);
    if (it_copied_stream != icc_profile_map_.end()) {
      return it_copied_stream->second;
    }
  }
  auto pProfile =
      pdfium::MakeRetain<CPDF_IccProfile>(pAccessor, expected_components);
  icc_profile_map_[pProfileStream] = pProfile;
  hash_icc_profile_map_[hash_profile_key] = std::move(pProfileStream);
  return pProfile;
}

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

  RetainPtr<const CPDF_Dictionary> font_dict = font_stream->GetDict();
  int32_t len1 = font_dict->GetIntegerFor("Length1");
  int32_t len2 = font_dict->GetIntegerFor("Length2");
  int32_t len3 = font_dict->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 font_acc = pdfium::MakeRetain<CPDF_StreamAcc>(font_stream);
  font_acc->LoadAllDataFilteredWithEstimatedSize(org_size);
  font_file_map_[std::move(font_stream)] = font_acc;
  return font_acc;
}

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

  RetainPtr<const CPDF_Stream> font_stream = stream_acc->GetStream();
  if (!font_stream) {
    return;
  }

  stream_acc.Reset();  // Drop moved caller's reference.
  auto it = font_file_map_.find(font_stream);
  if (it != font_file_map_.end() && it->second->HasOneRef()) {
    font_file_map_.erase(it);
  }
}

std::unique_ptr<CPDF_Font::FormIface> CPDF_DocPageData::CreateForm(
    CPDF_Document* document,
    RetainPtr<CPDF_Dictionary> pPageResources,
    RetainPtr<CPDF_Stream> pFormStream) {
  return std::make_unique<CPDF_Form>(document, 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> font,
                                               FX_Charset charset) {
  if (!font) {
    return nullptr;
  }

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

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

  auto charmap_resolver = CFX_CharmapResolver::CreateUnicode(font.get());
  RetainPtr<CPDF_Dictionary> font_dict = pBaseDict;
  if (!bCJK) {
    auto pWidths = pdfium::MakeRetain<CPDF_Array>();
    for (int charcode = 32; charcode < 128; charcode++) {
      int glyph_index = charmap_resolver->GlyphFromCharCode(charcode);
      int char_width = font->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 = charmap_resolver->GlyphFromCharCode(charcode);
        int char_width = font->GetGlyphWidth(glyph_index);
        pWidths->AppendNew<CPDF_Number>(char_width);
      }
    } else {
      size_t i = CalculateEncodingDict(charset, pBaseDict.Get());
      if (i < std::size(kFX_CharsetUnicodes)) {
        pdfium::span<const uint16_t> pUnicodes =
            kFX_CharsetUnicodes[i].unicodes_;
        for (int j = 0; j < 128; j++) {
          int glyph_index = charmap_resolver->GlyphFromCharCode(pUnicodes[j]);
          int char_width = font->GetGlyphWidth(glyph_index);
          pWidths->AppendNew<CPDF_Number>(char_width);
        }
      }
    }
    ProcessNonbCJK(pBaseDict, font->IsBold(), font->IsItalic(), basefont,
                   std::move(pWidths));
  } else {
    font_dict =
        ProcessbCJK(pBaseDict, charset, basefont,
                    [&font, &charmap_resolver](wchar_t start, wchar_t end,
                                               CPDF_Array* widthArr) {
                      InsertWidthArray1(font.get(), charmap_resolver.get(),
                                        start, end, widthArr);
                    });
  }
  int italicangle = font->GetSubstFontItalicAngle();
  FX_RECT bbox = font->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 (font->GetSubstFont()) {
    nStemV = font->GetSubstFont()->weight_ / 5;
  } else {
    static constexpr char kStemChars[] = {'i', 'I', '!', '1'};
    static constexpr pdfium::span<const char> kStemSpan{kStemChars};
    uint32_t glyph = charmap_resolver->GlyphFromCharCode(kStemSpan.front());
    const auto remaining = kStemSpan.subspan<1>();
    nStemV = font->GetGlyphWidth(glyph);
    for (auto ch : remaining) {
      glyph = charmap_resolver->GlyphFromCharCode(ch);
      int width = font->GetGlyphWidth(glyph);
      if (width > 0 && width < nStemV) {
        nStemV = width;
      }
    }
  }
  RetainPtr<CPDF_Dictionary> font_desc = CalculateFontDesc(
      GetDocument(), basefont, flags, italicangle, font->GetAscent(),
      font->GetDescent(), std::move(pBBox), nStemV);
  uint32_t new_objnum = GetDocument()->AddIndirectObject(std::move(font_desc));
  font_dict->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;
  std::array<int, 4> bbox = {{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> font_dict = 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());
    }
    std::array<int, 224> char_widths;
    GetCharWidth(hDC, 32, 255, char_widths.data());
    auto pWidths = pdfium::MakeRetain<CPDF_Array>();
    for (const auto char_width : char_widths) {
      pWidths->AppendNew<CPDF_Number>(char_width);
    }
    ProcessNonbCJK(pBaseDict, pLogFont->lfWeight > FW_MEDIUM,
                   pLogFont->lfItalic != 0, basefont, std::move(pWidths));
  } else {
    font_dict =
        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 (const auto bound : bbox) {
    pBBox->AppendNew<CPDF_Number>(bound);
  }
  RetainPtr<CPDF_Dictionary> font_desc =
      CalculateFontDesc(GetDocument(), basefont, flags, italicangle, ascend,
                        descend, std::move(pBBox), pLogFont->lfWeight / 5);
  font_desc->SetNewFor<CPDF_Number>("CapHeight", capheight);
  GetDocument()->AddIndirectObject(font_desc);
  font_dict->SetFor("FontDescriptor", font_desc->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].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);

  pdfium::span<const uint16_t> pUnicodes = kFX_CharsetUnicodes[i].unicodes_;
  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 font_dict = GetDocument()->NewIndirect<CPDF_Dictionary>();
  ByteString cmap;
  ByteString ordering;
  int supplement = 0;
  auto pWidthArray = font_dict->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);
  font_dict->SetNewFor<CPDF_Name>("Type", "Font");
  font_dict->SetNewFor<CPDF_Name>("Subtype", "CIDFontType2");
  font_dict->SetNewFor<CPDF_Name>("BaseFont", basefont);

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

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