// 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::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).first<2u>());
    // 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;
  // SAFETY: required from caller.
  auto charcodes_span = UNSAFE_BUFFERS(pdfium::span(charcodes, count));
  for (uint32_t c : charcodes_span) {
    pTextObj->GetFont()->AppendChar(&byte_text, c);
  }
  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::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::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::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->device_ = std::move(device);
  render_context_ptr->context_ = 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->context_.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);

  ValidateBitmapPremultiplyState(result_bitmap);

  // 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].fallback_font_position_ == -1) {
    pCfxFont = pFont->GetFont();
    DCHECK(pCfxFont);  // Never null.
  } else {
    pCfxFont = pFont->GetFontFallback(pos[0].fallback_font_position_);
    if (!pCfxFont) {
      return nullptr;
    }
  }

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

  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]);
}
