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

#include <algorithm>
#include <limits>
#include <map>
#include <memory>
#include <sstream>
#include <utility>
#include <vector>

#include "core/fpdfapi/font/cpdf_cidfont.h"
#include "core/fpdfapi/font/cpdf_font.h"
#include "core/fpdfapi/page/cpdf_docpagedata.h"
#include "core/fpdfapi/page/cpdf_textobject.h"
#include "core/fpdfapi/page/cpdf_textstate.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.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_string.h"
#include "core/fpdfapi/render/charposlist.h"
#include "core/fpdfapi/render/cpdf_pagerendercontext.h"
#include "core/fpdfapi/render/cpdf_rendercontext.h"
#include "core/fpdfapi/render/cpdf_renderstatus.h"
#include "core/fpdfapi/render/cpdf_textrenderer.h"
#include "core/fpdftext/cpdf_textpage.h"
#include "core/fxcrt/byteorder.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/check_op.h"
#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/containers/contains.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_memcpy_wrappers.h"
#include "core/fxcrt/fx_string_wrappers.h"
#include "core/fxcrt/numerics/safe_conversions.h"
#include "core/fxcrt/span_util.h"
#include "core/fxcrt/stl_util.h"
#include "core/fxcrt/utf16.h"
#include "core/fxge/cfx_defaultrenderdevice.h"
#include "core/fxge/cfx_fontmgr.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "core/fxge/fx_font.h"
#include "core/fxge/text_char_pos.h"
#include "fpdfsdk/cpdfsdk_helpers.h"
#include "public/fpdf_edit.h"

// These checks are here because core/ and public/ cannot depend on each other.
static_assert(static_cast<int>(TextRenderingMode::MODE_UNKNOWN) ==
                  FPDF_TEXTRENDERMODE_UNKNOWN,
              "TextRenderingMode::MODE_UNKNOWN value mismatch");
static_assert(static_cast<int>(TextRenderingMode::MODE_FILL) ==
                  FPDF_TEXTRENDERMODE_FILL,
              "TextRenderingMode::MODE_FILL value mismatch");
static_assert(static_cast<int>(TextRenderingMode::MODE_STROKE) ==
                  FPDF_TEXTRENDERMODE_STROKE,
              "TextRenderingMode::MODE_STROKE value mismatch");
static_assert(static_cast<int>(TextRenderingMode::MODE_FILL_STROKE) ==
                  FPDF_TEXTRENDERMODE_FILL_STROKE,
              "TextRenderingMode::MODE_FILL_STROKE value mismatch");
static_assert(static_cast<int>(TextRenderingMode::MODE_INVISIBLE) ==
                  FPDF_TEXTRENDERMODE_INVISIBLE,
              "TextRenderingMode::MODE_INVISIBLE value mismatch");
static_assert(static_cast<int>(TextRenderingMode::MODE_FILL_CLIP) ==
                  FPDF_TEXTRENDERMODE_FILL_CLIP,
              "TextRenderingMode::MODE_FILL_CLIP value mismatch");
static_assert(static_cast<int>(TextRenderingMode::MODE_STROKE_CLIP) ==
                  FPDF_TEXTRENDERMODE_STROKE_CLIP,
              "TextRenderingMode::MODE_STROKE_CLIP value mismatch");
static_assert(static_cast<int>(TextRenderingMode::MODE_FILL_STROKE_CLIP) ==
                  FPDF_TEXTRENDERMODE_FILL_STROKE_CLIP,
              "TextRenderingMode::MODE_FILL_STROKE_CLIP value mismatch");
static_assert(static_cast<int>(TextRenderingMode::MODE_CLIP) ==
                  FPDF_TEXTRENDERMODE_CLIP,
              "TextRenderingMode::MODE_CLIP value mismatch");
static_assert(static_cast<int>(TextRenderingMode::MODE_LAST) ==
                  FPDF_TEXTRENDERMODE_LAST,
              "TextRenderingMode::MODE_LAST value mismatch");

namespace {

constexpr uint32_t kMaxBfCharBfRangeEntries = 100;

ByteString BaseFontNameForType(const CFX_Font* font, int font_type) {
  ByteString name = font_type == FPDF_FONT_TYPE1 ? font->GetPsName()
                                                 : font->GetBaseFontName();
  return name.IsEmpty() ? CFX_Font::kUntitledFontName : name;
}

RetainPtr<CPDF_Dictionary> CreateCompositeFontDict(CPDF_Document* doc,
                                                   const CFX_Font* font,
                                                   int font_type,
                                                   const ByteString& name) {
  auto font_dict = doc->NewIndirect<CPDF_Dictionary>();
  font_dict->SetNewFor<CPDF_Name>("Type", "Font");
  font_dict->SetNewFor<CPDF_Name>("Subtype", "Type0");
  // TODO(npm): Get the correct encoding, if it's not identity.
  ByteString encoding = "Identity-H";
  font_dict->SetNewFor<CPDF_Name>("Encoding", encoding);
  font_dict->SetNewFor<CPDF_Name>(
      "BaseFont", font_type == FPDF_FONT_TYPE1 ? name + "-" + encoding : name);
  return font_dict;
}

RetainPtr<CPDF_Dictionary> CreateCidFontDict(CPDF_Document* doc,
                                             int font_type,
                                             const ByteString& name) {
  auto cid_font_dict = doc->NewIndirect<CPDF_Dictionary>();
  cid_font_dict->SetNewFor<CPDF_Name>("Type", "Font");
  cid_font_dict->SetNewFor<CPDF_Name>("Subtype", font_type == FPDF_FONT_TYPE1
                                                     ? "CIDFontType0"
                                                     : "CIDFontType2");
  cid_font_dict->SetNewFor<CPDF_Name>("BaseFont", name);

  // TODO(npm): Maybe use FT_Get_CID_Registry_Ordering_Supplement to get the
  // CIDSystemInfo
  auto cid_system_info_dict = doc->NewIndirect<CPDF_Dictionary>();
  cid_system_info_dict->SetNewFor<CPDF_String>("Registry", "Adobe");
  cid_system_info_dict->SetNewFor<CPDF_String>("Ordering", "Identity");
  cid_system_info_dict->SetNewFor<CPDF_Number>("Supplement", 0);
  cid_font_dict->SetNewFor<CPDF_Reference>("CIDSystemInfo", doc,
                                           cid_system_info_dict->GetObjNum());
  return cid_font_dict;
}

RetainPtr<CPDF_Dictionary> LoadFontDesc(CPDF_Document* doc,
                                        const ByteString& font_name,
                                        CFX_Font* font,
                                        pdfium::span<const uint8_t> font_data,
                                        int font_type) {
  auto font_descriptor_dict = doc->NewIndirect<CPDF_Dictionary>();
  font_descriptor_dict->SetNewFor<CPDF_Name>("Type", "FontDescriptor");
  font_descriptor_dict->SetNewFor<CPDF_Name>("FontName", font_name);
  int flags = 0;
  if (font->GetFace()->IsFixedWidth()) {
    flags |= pdfium::kFontStyleFixedPitch;
  }
  if (font_name.Contains("Serif"))
    flags |= pdfium::kFontStyleSerif;
  if (font->GetFace()->IsItalic()) {
    flags |= pdfium::kFontStyleItalic;
  }
  if (font->GetFace()->IsBold()) {
    flags |= pdfium::kFontStyleForceBold;
  }

  // TODO(npm): How do I know if a font is symbolic, script, allcap, smallcap?
  flags |= pdfium::kFontStyleNonSymbolic;

  font_descriptor_dict->SetNewFor<CPDF_Number>("Flags", flags);
  FX_RECT bbox = font->GetBBox().value_or(FX_RECT());
  font_descriptor_dict->SetRectFor("FontBBox", CFX_FloatRect(bbox));

  // TODO(npm): calculate italic angle correctly
  font_descriptor_dict->SetNewFor<CPDF_Number>("ItalicAngle",
                                               font->IsItalic() ? -12 : 0);

  font_descriptor_dict->SetNewFor<CPDF_Number>("Ascent", font->GetAscent());
  font_descriptor_dict->SetNewFor<CPDF_Number>("Descent", font->GetDescent());

  // TODO(npm): calculate the capheight, stemV correctly
  font_descriptor_dict->SetNewFor<CPDF_Number>("CapHeight", font->GetAscent());
  font_descriptor_dict->SetNewFor<CPDF_Number>("StemV",
                                               font->IsBold() ? 120 : 70);

  auto stream = doc->NewIndirect<CPDF_Stream>(font_data);
  // TODO(npm): Lengths for Type1 fonts.
  if (font_type == FPDF_FONT_TRUETYPE) {
    stream->GetMutableDict()->SetNewFor<CPDF_Number>(
        "Length1", pdfium::checked_cast<int>(font_data.size()));
  }
  ByteString font_file_key =
      font_type == FPDF_FONT_TYPE1 ? "FontFile" : "FontFile2";
  font_descriptor_dict->SetNewFor<CPDF_Reference>(font_file_key, doc,
                                                  stream->GetObjNum());
  return font_descriptor_dict;
}

RetainPtr<CPDF_Array> CreateWidthsArray(
    CPDF_Document* doc,
    const std::map<uint32_t, uint32_t>& widths) {
  auto widths_array = doc->NewIndirect<CPDF_Array>();
  for (auto it = widths.begin(); it != widths.end(); ++it) {
    auto next_it = std::next(it);

    if (next_it != widths.end() && next_it->first == it->first + 1 &&
        next_it->second == it->second) {
      // The array can have a group c_first c_last w: all CIDs in the range from
      // c_first to c_last will have width w
      widths_array->AppendNew<CPDF_Number>(static_cast<int>(it->first));

      while (next_it != widths.end() && next_it->first == it->first + 1 &&
             next_it->second == it->second) {
        it = next_it;
        next_it = std::next(it);
      }
      widths_array->AppendNew<CPDF_Number>(static_cast<int>(it->first));
      widths_array->AppendNew<CPDF_Number>(static_cast<int>(it->second));
      continue;
    }
    // Otherwise we can have a group of the form c [w1 w2 ...]: c has width
    // w1, c+1 has width w2, etc.
    // A group may contain only a single item, e.g. c[w]
    widths_array->AppendNew<CPDF_Number>(static_cast<int>(it->first));
    auto current_width_array = pdfium::MakeRetain<CPDF_Array>();
    current_width_array->AppendNew<CPDF_Number>(static_cast<int>(it->second));

    while (next_it != widths.end() && next_it->first == it->first + 1) {
      it = next_it;
      next_it = std::next(it);
      current_width_array->AppendNew<CPDF_Number>(static_cast<int>(it->second));
    }
    widths_array->Append(std::move(current_width_array));
  }
  return widths_array;
}

const char kToUnicodeStart[] =
    "/CIDInit /ProcSet findresource begin\n"
    "12 dict begin\n"
    "begincmap\n"
    "/CIDSystemInfo\n"
    "<</Registry (Adobe)\n"
    "/Ordering (Identity)\n"
    "/Supplement 0\n"
    ">> def\n"
    "/CMapName /Adobe-Identity-H def\n"
    "/CMapType 2 def\n"
    "1 begincodespacerange\n"
    "<0000> <FFFF>\n"
    "endcodespacerange\n";

const char kToUnicodeEnd[] =
    "endcmap\n"
    "CMapName currentdict /CMap defineresource pop\n"
    "end\n"
    "end\n";

void AddCharcode(fxcrt::ostringstream& buffer, uint32_t number) {
  CHECK_LE(number, 0xFFFF);
  buffer << "<";
  char ans[4];
  FXSYS_IntToFourHexChars(number, ans);
  for (char c : ans) {
    buffer << c;
  }
  buffer << ">";
}

// PDF spec 1.7 Section 5.9.2: "Unicode character sequences as expressed in
// UTF-16BE encoding." See https://en.wikipedia.org/wiki/UTF-16#Description
void AddUnicode(fxcrt::ostringstream& buffer, uint32_t unicode) {
  if (pdfium::IsHighSurrogate(unicode) || pdfium::IsLowSurrogate(unicode)) {
    unicode = 0;
  }

  char unicode_buf[8];
  pdfium::span<const char> unicode_span = FXSYS_ToUTF16BE(unicode, unicode_buf);
  CHECK(!unicode_span.empty());
  buffer << "<";
  for (char c : unicode_span) {
    buffer << c;
  }
  buffer << ">";
}

// Loads the charcode to unicode mapping into a stream
RetainPtr<CPDF_Stream> LoadUnicode(
    CPDF_Document* doc,
    const std::multimap<uint32_t, uint32_t>& to_unicode) {
  // A map charcode->unicode
  std::map<uint32_t, uint32_t> char_to_unicode_map;
  // A map <char_start, char_end> to vector v of unicode characters of size (end
  // - start + 1). This abbreviates: start->v[0], start+1->v[1], etc. PDF spec
  // 1.7 Section 5.9.2 says that only the last byte of the unicode may change.
  std::map<std::pair<uint32_t, uint32_t>, std::vector<uint32_t>>
      char_range_to_unicodes_map;
  // A map <start, end> -> unicode
  // This abbreviates: start->unicode, start+1->unicode+1, etc.
  // PDF spec 1.7 Section 5.9.2 says that only the last byte of the unicode may
  // change.
  std::map<std::pair<uint32_t, uint32_t>, uint32_t>
      char_range_to_consecutive_unicodes_map;

  // Calculate the maps
  for (auto it = to_unicode.begin(); it != to_unicode.end(); ++it) {
    uint32_t first_charcode = it->first;
    uint32_t first_unicode = it->second;
    {
      auto next_it = std::next(it);
      if (next_it == to_unicode.end() || first_charcode + 1 != next_it->first) {
        char_to_unicode_map[first_charcode] = first_unicode;
        continue;
      }
    }
    ++it;
    uint32_t current_charcode = it->first;
    uint32_t current_unicode = it->second;
    if (current_charcode % 256 == 0) {
      char_to_unicode_map[first_charcode] = first_unicode;
      char_to_unicode_map[current_charcode] = current_unicode;
      continue;
    }
    const size_t max_extra = 255 - (current_charcode % 256);
    auto next_it = std::next(it);
    if (first_unicode + 1 != current_unicode) {
      // Consecutive charcodes mapping to non-consecutive unicodes
      std::vector<uint32_t> unicodes = {first_unicode, current_unicode};
      for (size_t i = 0; i < max_extra; ++i) {
        if (next_it == to_unicode.end() ||
            current_charcode + 1 != next_it->first) {
          break;
        }
        ++it;
        ++current_charcode;
        unicodes.push_back(it->second);
        next_it = std::next(it);
      }
      CHECK_EQ(it->first - first_charcode + 1, unicodes.size());
      char_range_to_unicodes_map[std::make_pair(first_charcode, it->first)] =
          std::move(unicodes);
      continue;
    }
    // Consecutive charcodes mapping to consecutive unicodes
    for (size_t i = 0; i < max_extra; ++i) {
      if (next_it == to_unicode.end() ||
          current_charcode + 1 != next_it->first ||
          current_unicode + 1 != next_it->second) {
        break;
      }
      ++it;
      ++current_charcode;
      ++current_unicode;
      next_it = std::next(it);
    }
    char_range_to_consecutive_unicodes_map[std::make_pair(
        first_charcode, current_charcode)] = first_unicode;
  }

  fxcrt::ostringstream buffer;
  buffer << kToUnicodeStart;

  {
    // Add `char_to_unicode_map` to `buffer`.
    uint32_t to_process =
        pdfium::checked_cast<uint32_t>(char_to_unicode_map.size());
    auto it = char_to_unicode_map.begin();
    while (to_process) {
      const uint32_t to_process_this_iteration =
          std::min(to_process, kMaxBfCharBfRangeEntries);
      buffer << to_process_this_iteration << " beginbfchar\n";
      for (uint32_t i = 0; i < to_process_this_iteration; ++i) {
        CHECK(it != char_to_unicode_map.end());
        AddCharcode(buffer, it->first);
        buffer << " ";
        AddUnicode(buffer, it->second);
        buffer << "\n";
        ++it;
      }
      buffer << "endbfchar\n";
      to_process -= to_process_this_iteration;
    }
  }

  {
    // Add `char_range_to_unicodes_map` to `buffer`.
    uint32_t to_process =
        pdfium::checked_cast<uint32_t>(char_range_to_unicodes_map.size());
    auto it = char_range_to_unicodes_map.begin();
    while (to_process) {
      const uint32_t to_process_this_iteration =
          std::min(to_process, kMaxBfCharBfRangeEntries);
      buffer << to_process_this_iteration << " beginbfrange\n";
      for (uint32_t i = 0; i < to_process_this_iteration; ++i) {
        CHECK(it != char_range_to_unicodes_map.end());
        const std::pair<uint32_t, uint32_t>& charcode_range = it->first;
        AddCharcode(buffer, charcode_range.first);
        buffer << " ";
        AddCharcode(buffer, charcode_range.second);
        buffer << " [";
        auto unicodes = pdfium::make_span(it->second);
        AddUnicode(buffer, unicodes[0]);
        for (uint32_t code : unicodes.subspan(1u)) {
          buffer << " ";
          AddUnicode(buffer, code);
        }
        buffer << "]\n";
        ++it;
      }
      buffer << "endbfrange\n";
      to_process -= to_process_this_iteration;
    }
  }

  {
    // Add `char_range_to_consecutive_unicodes_map` to `buffer`.
    uint32_t to_process = pdfium::checked_cast<uint32_t>(
        char_range_to_consecutive_unicodes_map.size());
    auto it = char_range_to_consecutive_unicodes_map.begin();
    while (to_process) {
      const uint32_t to_process_this_iteration =
          std::min(to_process, kMaxBfCharBfRangeEntries);
      buffer << to_process_this_iteration << " beginbfrange\n";
      for (uint32_t i = 0; i < to_process_this_iteration; ++i) {
        CHECK(it != char_range_to_consecutive_unicodes_map.end());
        const std::pair<uint32_t, uint32_t>& charcode_range = it->first;
        AddCharcode(buffer, charcode_range.first);
        buffer << " ";
        AddCharcode(buffer, charcode_range.second);
        buffer << " ";
        AddUnicode(buffer, it->second);
        buffer << "\n";
        ++it;
      }
      buffer << "endbfrange\n";
      to_process -= to_process_this_iteration;
    }
  }

  buffer << kToUnicodeEnd;
  auto stream = doc->NewIndirect<CPDF_Stream>(&buffer);
  return stream;
}

void CreateDescendantFontsArray(CPDF_Document* doc,
                                CPDF_Dictionary* font_dict,
                                uint32_t cid_font_dict_obj_num) {
  auto descendant_fonts_dict =
      font_dict->SetNewFor<CPDF_Array>("DescendantFonts");
  descendant_fonts_dict->AppendNew<CPDF_Reference>(doc, cid_font_dict_obj_num);
}

RetainPtr<CPDF_Font> LoadSimpleFont(CPDF_Document* doc,
                                    std::unique_ptr<CFX_Font> font,
                                    pdfium::span<const uint8_t> font_data,
                                    int font_type) {
  // If it doesn't have a single char, just fail.
  RetainPtr<CFX_Face> face = font->GetFace();
  if (face->GetGlyphCount() <= 0) {
    return nullptr;
  }

  // Simple fonts have 1-byte charcodes only.
  static constexpr uint32_t kMaxSimpleFontChar = 0xFF;
  auto char_codes_and_indices =
      face->GetCharCodesAndIndices(kMaxSimpleFontChar);
  if (char_codes_and_indices.empty()) {
    return nullptr;
  }

  auto font_dict = doc->NewIndirect<CPDF_Dictionary>();
  font_dict->SetNewFor<CPDF_Name>("Type", "Font");
  font_dict->SetNewFor<CPDF_Name>(
      "Subtype", font_type == FPDF_FONT_TYPE1 ? "Type1" : "TrueType");
  const ByteString name = BaseFontNameForType(font.get(), font_type);
  font_dict->SetNewFor<CPDF_Name>("BaseFont", name);

  font_dict->SetNewFor<CPDF_Number>(
      "FirstChar", static_cast<int>(char_codes_and_indices[0].char_code));
  auto widths_array = doc->NewIndirect<CPDF_Array>();
  for (size_t i = 0; i < char_codes_and_indices.size(); ++i) {
    widths_array->AppendNew<CPDF_Number>(
        font->GetGlyphWidth(char_codes_and_indices[i].glyph_index));
    if (i > 0 && i < char_codes_and_indices.size() - 1) {
      for (uint32_t j = char_codes_and_indices[i - 1].char_code + 1;
           j < char_codes_and_indices[i].char_code; ++j) {
        widths_array->AppendNew<CPDF_Number>(0);
      }
    }
  }
  font_dict->SetNewFor<CPDF_Number>(
      "LastChar", static_cast<int>(char_codes_and_indices.back().char_code));
  font_dict->SetNewFor<CPDF_Reference>("Widths", doc,
                                       widths_array->GetObjNum());
  RetainPtr<CPDF_Dictionary> font_descriptor_dict =
      LoadFontDesc(doc, name, font.get(), font_data, font_type);

  font_dict->SetNewFor<CPDF_Reference>("FontDescriptor", doc,
                                       font_descriptor_dict->GetObjNum());
  return CPDF_DocPageData::FromDocument(doc)->GetFont(std::move(font_dict));
}

RetainPtr<CPDF_Font> LoadCompositeFont(CPDF_Document* doc,
                                       std::unique_ptr<CFX_Font> font,
                                       pdfium::span<const uint8_t> font_data,
                                       int font_type) {
  // If it doesn't have a single char, just fail.
  RetainPtr<CFX_Face> face = font->GetFace();
  if (face->GetGlyphCount() <= 0) {
    return nullptr;
  }

  auto char_codes_and_indices =
      face->GetCharCodesAndIndices(pdfium::kMaximumSupplementaryCodePoint);
  if (char_codes_and_indices.empty()) {
    return nullptr;
  }

  const ByteString name = BaseFontNameForType(font.get(), font_type);
  RetainPtr<CPDF_Dictionary> font_dict =
      CreateCompositeFontDict(doc, font.get(), font_type, name);

  RetainPtr<CPDF_Dictionary> cid_font_dict =
      CreateCidFontDict(doc, font_type, name);

  RetainPtr<CPDF_Dictionary> font_descriptor_dict =
      LoadFontDesc(doc, name, font.get(), font_data, font_type);
  cid_font_dict->SetNewFor<CPDF_Reference>("FontDescriptor", doc,
                                           font_descriptor_dict->GetObjNum());

  std::multimap<uint32_t, uint32_t> to_unicode;
  std::map<uint32_t, uint32_t> widths;
  for (const auto& item : char_codes_and_indices) {
    if (!pdfium::Contains(widths, item.glyph_index)) {
      widths[item.glyph_index] = font->GetGlyphWidth(item.glyph_index);
    }
    to_unicode.emplace(item.glyph_index, item.char_code);
  }
  RetainPtr<CPDF_Array> widths_array = CreateWidthsArray(doc, widths);
  cid_font_dict->SetNewFor<CPDF_Reference>("W", doc, widths_array->GetObjNum());

  // TODO(npm): Support vertical writing

  CreateDescendantFontsArray(doc, font_dict.Get(), cid_font_dict->GetObjNum());

  RetainPtr<CPDF_Stream> to_unicode_stream = LoadUnicode(doc, to_unicode);
  font_dict->SetNewFor<CPDF_Reference>("ToUnicode", doc,
                                       to_unicode_stream->GetObjNum());
  return CPDF_DocPageData::FromDocument(doc)->GetFont(font_dict);
}

RetainPtr<CPDF_Font> LoadCustomCompositeFont(
    CPDF_Document* doc,
    std::unique_ptr<CFX_Font> font,
    pdfium::span<const uint8_t> font_span,
    const char* to_unicode_cmap,
    pdfium::span<const uint8_t> cid_to_gid_map_span) {
  CHECK_LE(cid_to_gid_map_span.size(), std::numeric_limits<uint32_t>::max());

  // If it doesn't have a single char, just fail.
  RetainPtr<CFX_Face> face = font->GetFace();
  if (face->GetGlyphCount() <= 0) {
    return nullptr;
  }

  const ByteString name = BaseFontNameForType(font.get(), FPDF_FONT_TRUETYPE);
  RetainPtr<CPDF_Dictionary> font_dict =
      CreateCompositeFontDict(doc, font.get(), FPDF_FONT_TRUETYPE, name);

  RetainPtr<CPDF_Dictionary> cid_font_dict =
      CreateCidFontDict(doc, FPDF_FONT_TRUETYPE, name);

  RetainPtr<CPDF_Dictionary> font_descriptor =
      LoadFontDesc(doc, name, font.get(), font_span, FPDF_FONT_TRUETYPE);
  cid_font_dict->SetNewFor<CPDF_Reference>("FontDescriptor", doc,
                                           font_descriptor->GetObjNum());

  std::map<uint32_t, uint32_t> widths;
  for (size_t i = 0; i < cid_to_gid_map_span.size(); i += 2) {
    uint16_t glyph_index =
        fxcrt::GetUInt16MSBFirst(cid_to_gid_map_span.subspan(i, 2));
    // Safe to cast since `cid_to_gid_map_span` has a size limit.
    widths[static_cast<uint32_t>(i) / 2] = font->GetGlyphWidth(glyph_index);
  }

  RetainPtr<CPDF_Array> widths_array = CreateWidthsArray(doc, widths);
  cid_font_dict->SetNewFor<CPDF_Reference>("W", doc, widths_array->GetObjNum());

  auto cid_to_gid_map = doc->NewIndirect<CPDF_Stream>(cid_to_gid_map_span);
  cid_font_dict->SetNewFor<CPDF_Reference>("CIDToGIDMap", doc,
                                           cid_to_gid_map->GetObjNum());

  CreateDescendantFontsArray(doc, font_dict, cid_font_dict->GetObjNum());

  auto to_unicode_stream = doc->NewIndirect<CPDF_Stream>(
      ByteStringView(to_unicode_cmap).unsigned_span());
  font_dict->SetNewFor<CPDF_Reference>("ToUnicode", doc,
                                       to_unicode_stream->GetObjNum());
  return CPDF_DocPageData::FromDocument(doc)->GetFont(font_dict);
}

CPDF_TextObject* CPDFTextObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object) {
  auto* obj = CPDFPageObjectFromFPDFPageObject(page_object);
  return obj ? obj->AsText() : nullptr;
}

FPDF_GLYPHPATH FPDFGlyphPathFromCFXPath(const CFX_Path* path) {
  return reinterpret_cast<FPDF_GLYPHPATH>(path);
}
const CFX_Path* CFXPathFromFPDFGlyphPath(FPDF_GLYPHPATH path) {
  return reinterpret_cast<const CFX_Path*>(path);
}

}  // namespace

FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV
FPDFPageObj_NewTextObj(FPDF_DOCUMENT document,
                       FPDF_BYTESTRING font,
                       float font_size) {
  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
  if (!pDoc)
    return nullptr;

  RetainPtr<CPDF_Font> pFont =
      CPDF_Font::GetStockFont(pDoc, ByteStringView(font));
  if (!pFont)
    return nullptr;

  auto pTextObj = std::make_unique<CPDF_TextObject>();
  pTextObj->mutable_text_state().SetFont(std::move(pFont));
  pTextObj->mutable_text_state().SetFontSize(font_size);
  pTextObj->SetDefaultStates();

  // Caller takes ownership.
  return FPDFPageObjectFromCPDFPageObject(pTextObj.release());
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFText_SetText(FPDF_PAGEOBJECT text_object, FPDF_WIDESTRING text) {
  CPDF_TextObject* pTextObj = CPDFTextObjectFromFPDFPageObject(text_object);
  if (!pTextObj) {
    return false;
  }
  // SAFETY: required from caller.
  WideString encodedText = UNSAFE_BUFFERS(WideStringFromFPDFWideString(text));
  ByteString byteText;
  for (wchar_t wc : encodedText) {
    pTextObj->GetFont()->AppendChar(
        &byteText, pTextObj->GetFont()->CharCodeFromUnicode(wc));
  }
  pTextObj->SetText(byteText);
  return true;
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFText_SetCharcodes(FPDF_PAGEOBJECT text_object,
                      const uint32_t* charcodes,
                      size_t count) {
  CPDF_TextObject* pTextObj = CPDFTextObjectFromFPDFPageObject(text_object);
  if (!pTextObj)
    return false;

  if (!charcodes && count)
    return false;

  ByteString byte_text;
  if (charcodes) {
    for (size_t i = 0; i < count; ++i) {
      pTextObj->GetFont()->AppendChar(&byte_text, UNSAFE_TODO(charcodes[i]));
    }
  }
  pTextObj->SetText(byte_text);
  return true;
}

FPDF_EXPORT FPDF_FONT FPDF_CALLCONV FPDFText_LoadFont(FPDF_DOCUMENT document,
                                                      const uint8_t* data,
                                                      uint32_t size,
                                                      int font_type,
                                                      FPDF_BOOL cid) {
  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
  if (!pDoc || !data || size == 0 ||
      (font_type != FPDF_FONT_TYPE1 && font_type != FPDF_FONT_TRUETYPE)) {
    return nullptr;
  }
  // SAFETY: required from caller.
  auto span = UNSAFE_BUFFERS(pdfium::make_span(data, size));
  auto pFont = std::make_unique<CFX_Font>();

  // TODO(npm): Maybe use FT_Get_X11_Font_Format to check format? Otherwise, we
  // are allowing giving any font that can be loaded on freetype and setting it
  // as any font type.
  if (!pFont->LoadEmbedded(span, /*force_vertical=*/false, /*object_tag=*/0))
    return nullptr;

  // Caller takes ownership.
  return FPDFFontFromCPDFFont(
      cid ? LoadCompositeFont(pDoc, std::move(pFont), span, font_type).Leak()
          : LoadSimpleFont(pDoc, std::move(pFont), span, font_type).Leak());
}

FPDF_EXPORT FPDF_FONT FPDF_CALLCONV
FPDFText_LoadStandardFont(FPDF_DOCUMENT document, FPDF_BYTESTRING font) {
  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
  if (!pDoc)
    return nullptr;

  // Caller takes ownership.
  return FPDFFontFromCPDFFont(
      CPDF_Font::GetStockFont(pDoc, ByteStringView(font)).Leak());
}

FPDF_EXPORT FPDF_FONT FPDF_CALLCONV
FPDFText_LoadCidType2Font(FPDF_DOCUMENT document,
                          const uint8_t* font_data,
                          uint32_t font_data_size,
                          FPDF_BYTESTRING to_unicode_cmap,
                          const uint8_t* cid_to_gid_map_data,
                          uint32_t cid_to_gid_map_data_size) {
  CPDF_Document* doc = CPDFDocumentFromFPDFDocument(document);
  if (!doc || !font_data || font_data_size == 0 || !to_unicode_cmap ||
      !cid_to_gid_map_data || cid_to_gid_map_data_size == 0) {
    return nullptr;
  }
  // SAFETY: required from caller.
  if (UNSAFE_BUFFERS(strlen(to_unicode_cmap)) == 0) {
    return nullptr;
  }
  // SAFETY: required from caller.
  auto font_span = UNSAFE_BUFFERS(pdfium::make_span(font_data, font_data_size));
  auto font = std::make_unique<CFX_Font>();

  // TODO(thestig): Consider checking the font format. See similar comment in
  // FPDFText_LoadFont() above.
  if (!font->LoadEmbedded(font_span, /*force_vertical=*/false,
                          /*object_tag=*/0)) {
    return nullptr;
  }

  // Caller takes ownership of result.
  // SAFETY: caller ensures `cid_to_gid_map_data` points to at least
  // `cid_to_gid_map_data_size` entries.
  return FPDFFontFromCPDFFont(
      LoadCustomCompositeFont(
          doc, std::move(font), font_span, to_unicode_cmap,
          UNSAFE_BUFFERS(
              pdfium::make_span(cid_to_gid_map_data, cid_to_gid_map_data_size)))
          .Leak());
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFTextObj_GetFontSize(FPDF_PAGEOBJECT text, float* size) {
  if (!size)
    return false;

  CPDF_TextObject* pTextObj = CPDFTextObjectFromFPDFPageObject(text);
  if (!pTextObj)
    return false;

  *size = pTextObj->GetFontSize();
  return true;
}

FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFTextObj_GetText(FPDF_PAGEOBJECT text_object,
                    FPDF_TEXTPAGE text_page,
                    FPDF_WCHAR* buffer,
                    unsigned long length) {
  CPDF_TextObject* pTextObj = CPDFTextObjectFromFPDFPageObject(text_object);
  if (!pTextObj)
    return 0;

  CPDF_TextPage* pTextPage = CPDFTextPageFromFPDFTextPage(text_page);
  if (!pTextPage)
    return 0;

  // SAFETY: required from caller.
  return Utf16EncodeMaybeCopyAndReturnLength(
      pTextPage->GetTextByObject(pTextObj),
      UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, length)));
}

FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
FPDFTextObj_GetRenderedBitmap(FPDF_DOCUMENT document,
                              FPDF_PAGE page,
                              FPDF_PAGEOBJECT text_object,
                              float scale) {
  CPDF_Document* doc = CPDFDocumentFromFPDFDocument(document);
  if (!doc)
    return nullptr;

  CPDF_Page* optional_page = CPDFPageFromFPDFPage(page);
  if (optional_page && optional_page->GetDocument() != doc)
    return nullptr;

  CPDF_TextObject* text = CPDFTextObjectFromFPDFPageObject(text_object);
  if (!text)
    return nullptr;

  if (scale <= 0)
    return nullptr;

  const CFX_Matrix scale_matrix(scale, 0, 0, scale, 0, 0);
  const CFX_FloatRect& text_rect = text->GetRect();
  const CFX_FloatRect scaled_text_rect = scale_matrix.TransformRect(text_rect);

  // `rect` has to use integer values. Round up as needed.
  const FX_RECT rect = scaled_text_rect.GetOuterRect();
  if (rect.IsEmpty())
    return nullptr;

  // TODO(crbug.com/42271020): Consider adding support for
  // `FXDIB_Format::kBgraPremul`
  auto result_bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
  if (!result_bitmap->Create(rect.Width(), rect.Height(),
                             FXDIB_Format::kBgra)) {
    return nullptr;
  }

  auto render_context = std::make_unique<CPDF_PageRenderContext>();
  CPDF_PageRenderContext* render_context_ptr = render_context.get();
  CPDF_Page::RenderContextClearer clearer(optional_page);
  if (optional_page)
    optional_page->SetRenderContext(std::move(render_context));

  RetainPtr<CPDF_Dictionary> page_resources =
      optional_page ? optional_page->GetMutablePageResources() : nullptr;

  auto device = std::make_unique<CFX_DefaultRenderDevice>();
  CFX_DefaultRenderDevice* device_ptr = device.get();
  render_context_ptr->m_pDevice = std::move(device);
  render_context_ptr->m_pContext = std::make_unique<CPDF_RenderContext>(
      doc, std::move(page_resources), /*pPageCache=*/nullptr);

  device_ptr->Attach(result_bitmap);

  CFX_Matrix device_matrix(rect.Width(), 0, 0, rect.Height(), 0, 0);
  CPDF_RenderStatus status(render_context_ptr->m_pContext.get(), device_ptr);
  status.SetDeviceMatrix(device_matrix);
  status.Initialize(nullptr, nullptr);

  // Need to flip the rendering and also move it to fit within `result_bitmap`.
  CFX_Matrix render_matrix(1, 0, 0, -1, -text_rect.left, text_rect.top);
  render_matrix *= scale_matrix;
  status.RenderSingleObject(text, render_matrix);

  CHECK(!result_bitmap->IsPremultiplied());

  // Caller takes ownership.
  return FPDFBitmapFromCFXDIBitmap(result_bitmap.Leak());
}

FPDF_EXPORT void FPDF_CALLCONV FPDFFont_Close(FPDF_FONT font) {
  // Take back ownership from caller and release.
  RetainPtr<CPDF_Font>().Unleak(CPDFFontFromFPDFFont(font));
}

FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV
FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document,
                          FPDF_FONT font,
                          float font_size) {
  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
  CPDF_Font* pFont = CPDFFontFromFPDFFont(font);
  if (!pDoc || !pFont)
    return nullptr;

  auto pTextObj = std::make_unique<CPDF_TextObject>();
  pTextObj->mutable_text_state().SetFont(
      CPDF_DocPageData::FromDocument(pDoc)->GetFont(
          pFont->GetMutableFontDict()));
  pTextObj->mutable_text_state().SetFontSize(font_size);
  pTextObj->SetDefaultStates();
  return FPDFPageObjectFromCPDFPageObject(pTextObj.release());
}

FPDF_EXPORT FPDF_TEXT_RENDERMODE FPDF_CALLCONV
FPDFTextObj_GetTextRenderMode(FPDF_PAGEOBJECT text) {
  CPDF_TextObject* pTextObj = CPDFTextObjectFromFPDFPageObject(text);
  if (!pTextObj)
    return FPDF_TEXTRENDERMODE_UNKNOWN;
  return static_cast<FPDF_TEXT_RENDERMODE>(pTextObj->GetTextRenderMode());
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFTextObj_SetTextRenderMode(FPDF_PAGEOBJECT text,
                              FPDF_TEXT_RENDERMODE render_mode) {
  if (render_mode <= FPDF_TEXTRENDERMODE_UNKNOWN ||
      render_mode > FPDF_TEXTRENDERMODE_LAST) {
    return false;
  }

  CPDF_TextObject* pTextObj = CPDFTextObjectFromFPDFPageObject(text);
  if (!pTextObj)
    return false;

  pTextObj->SetTextRenderMode(static_cast<TextRenderingMode>(render_mode));
  return true;
}

FPDF_EXPORT FPDF_FONT FPDF_CALLCONV FPDFTextObj_GetFont(FPDF_PAGEOBJECT text) {
  CPDF_TextObject* pTextObj = CPDFTextObjectFromFPDFPageObject(text);
  if (!pTextObj)
    return nullptr;

  // Unretained reference in public API. NOLINTNEXTLINE
  return FPDFFontFromCPDFFont(pTextObj->GetFont());
}

FPDF_EXPORT size_t FPDF_CALLCONV FPDFFont_GetBaseFontName(FPDF_FONT font,
                                                          char* buffer,
                                                          size_t length) {
  auto* cfont = CPDFFontFromFPDFFont(font);
  if (!cfont) {
    return 0;
  }

  // SAFETY: required from caller.
  auto result_span = UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, length));
  ByteString name = cfont->GetBaseFontName();
  pdfium::span<const char> name_span = name.span_with_terminator();
  fxcrt::try_spancpy(result_span, name_span);
  return name_span.size();
}

FPDF_EXPORT size_t FPDF_CALLCONV FPDFFont_GetFamilyName(FPDF_FONT font,
                                                        char* buffer,
                                                        size_t length) {
  auto* cfont = CPDFFontFromFPDFFont(font);
  if (!cfont) {
    return 0;
  }

  // SAFETY: required from caller.
  auto result_span = UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, length));
  ByteString name = cfont->GetFont()->GetFamilyName();
  pdfium::span<const char> name_span = name.span_with_terminator();
  fxcrt::try_spancpy(result_span, name_span);
  return name_span.size();
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFFont_GetFontData(FPDF_FONT font,
                                                         uint8_t* buffer,
                                                         size_t buflen,
                                                         size_t* out_buflen) {
  auto* cfont = CPDFFontFromFPDFFont(font);
  if (!cfont || !out_buflen)
    return false;

  // SAFETY: required from caller.
  auto result_span = UNSAFE_BUFFERS(SpanFromFPDFApiArgs(buffer, buflen));
  pdfium::span<const uint8_t> data = cfont->GetFont()->GetFontSpan();
  fxcrt::try_spancpy(result_span, data);
  *out_buflen = data.size();
  return true;
}

FPDF_EXPORT int FPDF_CALLCONV FPDFFont_GetIsEmbedded(FPDF_FONT font) {
  auto* cfont = CPDFFontFromFPDFFont(font);
  if (!cfont)
    return -1;
  return cfont->IsEmbedded() ? 1 : 0;
}

FPDF_EXPORT int FPDF_CALLCONV FPDFFont_GetFlags(FPDF_FONT font) {
  auto* pFont = CPDFFontFromFPDFFont(font);
  if (!pFont)
    return -1;

  // Return only flags from ISO 32000-1:2008, table 123.
  return pFont->GetFontFlags() & 0x7ffff;
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFFont_GetWeight(FPDF_FONT font) {
  auto* cfont = CPDFFontFromFPDFFont(font);
  if (!cfont) {
    return -1;
  }
  return cfont->GetFontWeight().value_or(-1);
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFFont_GetItalicAngle(FPDF_FONT font,
                                                            int* angle) {
  auto* pFont = CPDFFontFromFPDFFont(font);
  if (!pFont || !angle)
    return false;

  *angle = pFont->GetItalicAngle();
  return true;
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFFont_GetAscent(FPDF_FONT font,
                                                       float font_size,
                                                       float* ascent) {
  auto* pFont = CPDFFontFromFPDFFont(font);
  if (!pFont || !ascent)
    return false;

  *ascent = pFont->GetTypeAscent() * font_size / 1000.f;
  return true;
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFFont_GetDescent(FPDF_FONT font,
                                                        float font_size,
                                                        float* descent) {
  auto* pFont = CPDFFontFromFPDFFont(font);
  if (!pFont || !descent)
    return false;

  *descent = pFont->GetTypeDescent() * font_size / 1000.f;
  return true;
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFFont_GetGlyphWidth(FPDF_FONT font,
                                                           uint32_t glyph,
                                                           float font_size,
                                                           float* width) {
  auto* pFont = CPDFFontFromFPDFFont(font);
  if (!pFont || !width)
    return false;

  uint32_t charcode = pFont->CharCodeFromUnicode(static_cast<wchar_t>(glyph));

  CPDF_CIDFont* pCIDFont = pFont->AsCIDFont();
  if (pCIDFont && pCIDFont->IsVertWriting()) {
    uint16_t cid = pCIDFont->CIDFromCharCode(charcode);
    *width = pCIDFont->GetVertWidth(cid) * font_size / 1000.f;
  } else {
    *width = pFont->GetCharWidthF(charcode) * font_size / 1000.f;
  }

  return true;
}

FPDF_EXPORT FPDF_GLYPHPATH FPDF_CALLCONV
FPDFFont_GetGlyphPath(FPDF_FONT font, uint32_t glyph, float font_size) {
  auto* pFont = CPDFFontFromFPDFFont(font);
  if (!pFont)
    return nullptr;

  if (!pdfium::IsValueInRangeForNumericType<wchar_t>(glyph)) {
    return nullptr;
  }

  uint32_t charcode = pFont->CharCodeFromUnicode(static_cast<wchar_t>(glyph));
  std::vector<TextCharPos> pos =
      GetCharPosList(pdfium::span_from_ref(charcode),
                     pdfium::span<const float>(), pFont, font_size);
  if (pos.empty())
    return nullptr;

  CFX_Font* pCfxFont;
  if (pos[0].m_FallbackFontPosition == -1) {
    pCfxFont = pFont->GetFont();
    DCHECK(pCfxFont);  // Never null.
  } else {
    pCfxFont = pFont->GetFontFallback(pos[0].m_FallbackFontPosition);
    if (!pCfxFont)
      return nullptr;
  }

  const CFX_Path* pPath =
      pCfxFont->LoadGlyphPath(pos[0].m_GlyphIndex, pos[0].m_FontCharWidth);

  return FPDFGlyphPathFromCFXPath(pPath);
}

FPDF_EXPORT int FPDF_CALLCONV
FPDFGlyphPath_CountGlyphSegments(FPDF_GLYPHPATH glyphpath) {
  auto* pPath = CFXPathFromFPDFGlyphPath(glyphpath);
  if (!pPath)
    return -1;

  return fxcrt::CollectionSize<int>(pPath->GetPoints());
}

FPDF_EXPORT FPDF_PATHSEGMENT FPDF_CALLCONV
FPDFGlyphPath_GetGlyphPathSegment(FPDF_GLYPHPATH glyphpath, int index) {
  auto* pPath = CFXPathFromFPDFGlyphPath(glyphpath);
  if (!pPath)
    return nullptr;

  pdfium::span<const CFX_Path::Point> points = pPath->GetPoints();
  if (!fxcrt::IndexInBounds(points, index))
    return nullptr;

  return FPDFPathSegmentFromFXPathPoint(&points[index]);
}
