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

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#ifndef CORE_FXGE_WIN32_CFX_PSRENDERER_H_
#define CORE_FXGE_WIN32_CFX_PSRENDERER_H_

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <sstream>
#include <vector>

#include "core/fxcrt/bytestring.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_memory_wrappers.h"
#include "core/fxcrt/fx_stream.h"
#include "core/fxcrt/fx_string_wrappers.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/unowned_ptr.h"
#include "core/fxge/cfx_graphstatedata.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/base/span.h"

class CFX_DIBBase;
class CFX_Font;
class CFX_GlyphCache;
class CFX_PSFontTracker;
class CFX_Path;
class TextCharPos;
struct CFX_FillRenderOptions;
struct FXDIB_ResampleOptions;

struct EncoderIface {
  DataVector<uint8_t> (*pA85EncodeFunc)(pdfium::span<const uint8_t> src_span);
  DataVector<uint8_t> (*pFaxEncodeFunc)(RetainPtr<CFX_DIBBase> src);
  DataVector<uint8_t> (*pFlateEncodeFunc)(pdfium::span<const uint8_t> src_span);
  bool (*pJpegEncodeFunc)(const RetainPtr<CFX_DIBBase>& pSource,
                          uint8_t** dest_buf,
                          size_t* dest_size);
  DataVector<uint8_t> (*pRunLengthEncodeFunc)(
      pdfium::span<const uint8_t> src_span);
};

class CFX_PSRenderer {
 public:
  enum class RenderingLevel {
    kLevel2,
    kLevel3,
    kLevel3Type42,
  };

  CFX_PSRenderer(CFX_PSFontTracker* font_tracker,
                 const EncoderIface* encoder_iface);
  ~CFX_PSRenderer();

  void Init(const RetainPtr<IFX_RetainableWriteStream>& stream,
            RenderingLevel level,
            int width,
            int height);
  void SaveState();
  void RestoreState(bool bKeepSaved);
  void SetClip_PathFill(const CFX_Path& path,
                        const CFX_Matrix* pObject2Device,
                        const CFX_FillRenderOptions& fill_options);
  void SetClip_PathStroke(const CFX_Path& path,
                          const CFX_Matrix* pObject2Device,
                          const CFX_GraphStateData* pGraphState);
  FX_RECT GetClipBox() { return m_ClipBox; }
  bool DrawPath(const CFX_Path& path,
                const CFX_Matrix* pObject2Device,
                const CFX_GraphStateData* pGraphState,
                uint32_t fill_color,
                uint32_t stroke_color,
                const CFX_FillRenderOptions& fill_options);
  bool SetDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                 uint32_t color,
                 int dest_left,
                 int dest_top);
  bool StretchDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                     uint32_t color,
                     int dest_left,
                     int dest_top,
                     int dest_width,
                     int dest_height,
                     const FXDIB_ResampleOptions& options);
  bool DrawDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                  uint32_t color,
                  const CFX_Matrix& matrix,
                  const FXDIB_ResampleOptions& options);
  bool DrawText(int nChars,
                const TextCharPos* pCharPos,
                CFX_Font* pFont,
                const CFX_Matrix& mtObject2Device,
                float font_size,
                uint32_t color);

  static absl::optional<ByteString> GenerateType42SfntDataForTesting(
      const ByteString& psname,
      pdfium::span<const uint8_t> font_data);

  static ByteString GenerateType42FontDictionaryForTesting(
      const ByteString& psname,
      const FX_RECT& bbox,
      size_t num_glyphs,
      size_t glyphs_per_descendant_font);

 private:
  struct Glyph;

  struct FaxCompressResult {
    FaxCompressResult();
    FaxCompressResult(const FaxCompressResult&) = delete;
    FaxCompressResult& operator=(const FaxCompressResult&) = delete;
    FaxCompressResult(FaxCompressResult&&) noexcept;
    FaxCompressResult& operator=(FaxCompressResult&&) noexcept;
    ~FaxCompressResult();

    DataVector<uint8_t> data;
    bool compressed;
  };

  struct PSCompressResult {
    PSCompressResult();
    PSCompressResult(const PSCompressResult&) = delete;
    PSCompressResult& operator=(const PSCompressResult&) = delete;
    PSCompressResult(PSCompressResult&&) noexcept;
    PSCompressResult& operator=(PSCompressResult&&) noexcept;
    ~PSCompressResult();

    DataVector<uint8_t> data;
    ByteString filter;
  };

  void StartRendering();
  void EndRendering();
  void OutputPath(const CFX_Path& path, const CFX_Matrix* pObject2Device);
  void SetGraphState(const CFX_GraphStateData* pGraphState);
  void SetColor(uint32_t color);
  void FindPSFontGlyph(CFX_GlyphCache* pGlyphCache,
                       CFX_Font* pFont,
                       const TextCharPos& charpos,
                       int* ps_fontnum,
                       int* ps_glyphindex);
  void DrawTextAsType3Font(int char_count,
                           const TextCharPos* char_pos,
                           CFX_Font* font,
                           float font_size,
                           fxcrt::ostringstream& buf);
  bool DrawTextAsType42Font(int char_count,
                            const TextCharPos* char_pos,
                            CFX_Font* font,
                            float font_size,
                            fxcrt::ostringstream& buf);
  FaxCompressResult FaxCompressData(RetainPtr<CFX_DIBBase> src) const;
  absl::optional<PSCompressResult> PSCompressData(
      pdfium::span<const uint8_t> src_span) const;
  void WritePreambleString(ByteStringView str);
  void WritePSBinary(pdfium::span<const uint8_t> data);
  void WriteStream(fxcrt::ostringstream& stream);
  void WriteString(ByteStringView str);

  bool m_bInited = false;
  bool m_bGraphStateSet = false;
  bool m_bColorSet = false;
  absl::optional<RenderingLevel> m_Level;
  uint32_t m_LastColor = 0;
  FX_RECT m_ClipBox;
  CFX_GraphStateData m_CurGraphState;
  UnownedPtr<CFX_PSFontTracker> const m_pFontTracker;
  UnownedPtr<const EncoderIface> const m_pEncoderIface;
  RetainPtr<IFX_RetainableWriteStream> m_pStream;
  std::vector<std::unique_ptr<Glyph>> m_PSFontList;
  fxcrt::ostringstream m_PreambleOutput;
  fxcrt::ostringstream m_Output;
  std::vector<FX_RECT> m_ClipBoxStack;
};

#endif  // CORE_FXGE_WIN32_CFX_PSRENDERER_H_
