// Copyright 2014 PDFium Authors. All rights reserved.
// 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_INCLUDE_FPDFAPI_FPDF_PAGEOBJ_H_
#define CORE_INCLUDE_FPDFAPI_FPDF_PAGEOBJ_H_

#include "../fxge/fx_ge.h"
#include "fpdf_resource.h"

class CPDF_Path;
class CPDF_ClipPathData;
class CPDF_ClipPath;
class CPDF_ColorStateData;
class CPDF_ColorState;
class CPDF_GraphState;
class CPDF_TextStateData;
class CPDF_TextState;
class CPDF_GeneralStateData;
class CPDF_GeneralState;
class CPDF_ContentMarkItem;
class CPDF_ContentMark;
class CPDF_GraphicStates;
class CPDF_PageObject;
class CPDF_TextObject;
class CPDF_PathObject;
class CPDF_ImageObject;
class CPDF_ShadingObject;
class CPDF_FormObject;
typedef CFX_PathData CPDF_PathData;

class CPDF_Path : public CFX_CountRef<CFX_PathData> {
 public:
  int GetPointCount() { return m_pObject->m_PointCount; }

  int GetFlag(int index) { return m_pObject->m_pPoints[index].m_Flag; }

  FX_FLOAT GetPointX(int index) { return m_pObject->m_pPoints[index].m_PointX; }

  FX_FLOAT GetPointY(int index) { return m_pObject->m_pPoints[index].m_PointY; }

  FX_PATHPOINT* GetPoints() { return m_pObject->m_pPoints; }

  CFX_FloatRect GetBoundingBox() const { return m_pObject->GetBoundingBox(); }

  CFX_FloatRect GetBoundingBox(FX_FLOAT line_width,
                               FX_FLOAT miter_limit) const {
    return m_pObject->GetBoundingBox(line_width, miter_limit);
  }

  void Transform(const CFX_AffineMatrix* pMatrix) {
    GetModify()->Transform(pMatrix);
  }

  void Append(CPDF_Path src, const CFX_AffineMatrix* pMatrix) {
    m_pObject->Append(src.m_pObject, pMatrix);
  }

  void AppendRect(FX_FLOAT left,
                  FX_FLOAT bottom,
                  FX_FLOAT right,
                  FX_FLOAT top) {
    m_pObject->AppendRect(left, bottom, right, top);
  }

  FX_BOOL IsRect() const { return m_pObject->IsRect(); }
};
class CPDF_ClipPathData {
 public:
  CPDF_ClipPathData();

  CPDF_ClipPathData(const CPDF_ClipPathData&);

  ~CPDF_ClipPathData();

  void SetCount(int path_count, int text_count);

 public:
  int m_PathCount;

  CPDF_Path* m_pPathList;

  uint8_t* m_pTypeList;

  int m_TextCount;

  CPDF_TextObject** m_pTextList;
};
class CPDF_ClipPath : public CFX_CountRef<CPDF_ClipPathData> {
 public:
  FX_DWORD GetPathCount() const { return m_pObject->m_PathCount; }

  CPDF_Path GetPath(int i) const { return m_pObject->m_pPathList[i]; }

  int GetClipType(int i) const { return m_pObject->m_pTypeList[i]; }

  FX_DWORD GetTextCount() const { return m_pObject->m_TextCount; }

  CPDF_TextObject* GetText(int i) const { return m_pObject->m_pTextList[i]; }

  CFX_FloatRect GetClipBox() const;

  void AppendPath(CPDF_Path path, int type, FX_BOOL bAutoMerge);

  void DeletePath(int layer_index);

  void AppendTexts(CPDF_TextObject** pTexts, int count);

  void Transform(const CFX_AffineMatrix& matrix);
};
class CPDF_ColorStateData {
 public:
  CPDF_ColorStateData() : m_FillRGB(0), m_StrokeRGB(0) {}

  CPDF_ColorStateData(const CPDF_ColorStateData& src);

  void Default();

  CPDF_Color m_FillColor;

  FX_DWORD m_FillRGB;

  CPDF_Color m_StrokeColor;

  FX_DWORD m_StrokeRGB;
};
class CPDF_ColorState : public CFX_CountRef<CPDF_ColorStateData> {
 public:
  CPDF_Color* GetFillColor() const {
    return m_pObject ? &m_pObject->m_FillColor : NULL;
  }

  CPDF_Color* GetStrokeColor() const {
    return m_pObject ? &m_pObject->m_StrokeColor : NULL;
  }

  void SetFillColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues);

  void SetStrokeColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues);

  void SetFillPattern(CPDF_Pattern* pattern, FX_FLOAT* pValue, int nValues);

  void SetStrokePattern(CPDF_Pattern* pattern, FX_FLOAT* pValue, int nValues);

 private:
  void SetColor(CPDF_Color& color,
                FX_DWORD& rgb,
                CPDF_ColorSpace* pCS,
                FX_FLOAT* pValue,
                int nValues);
};
typedef CFX_GraphStateData CPDF_GraphStateData;
class CPDF_GraphState : public CFX_CountRef<CFX_GraphStateData> {
 public:
};
class CPDF_TextStateData {
 public:
  CPDF_TextStateData();

  CPDF_TextStateData(const CPDF_TextStateData& src);

  ~CPDF_TextStateData();

  CPDF_Font* m_pFont;

  CPDF_Document* m_pDocument;

  FX_FLOAT m_FontSize;

  FX_FLOAT m_CharSpace;

  FX_FLOAT m_WordSpace;

  FX_FLOAT m_Matrix[4];

  int m_TextMode;

  FX_FLOAT m_CTM[4];
};
class CPDF_TextState : public CFX_CountRef<CPDF_TextStateData> {
 public:
  CPDF_Font* GetFont() const { return m_pObject->m_pFont; }

  void SetFont(CPDF_Font* pFont);

  FX_FLOAT GetFontSize() const { return m_pObject->m_FontSize; }

  FX_FLOAT* GetMatrix() const { return m_pObject->m_Matrix; }

  FX_FLOAT GetFontSizeV() const;

  FX_FLOAT GetFontSizeH() const;

  FX_FLOAT GetBaselineAngle() const;

  FX_FLOAT GetShearAngle() const;
};
class CPDF_TransferFunc;
class CPDF_GeneralStateData {
 public:
  CPDF_GeneralStateData();

  CPDF_GeneralStateData(const CPDF_GeneralStateData& src);
  ~CPDF_GeneralStateData();

  void SetBlendMode(const CFX_ByteStringC& blend_mode);

  char m_BlendMode[16];

  int m_BlendType;

  CPDF_Object* m_pSoftMask;

  FX_FLOAT m_SMaskMatrix[6];

  FX_FLOAT m_StrokeAlpha;

  FX_FLOAT m_FillAlpha;

  CPDF_Object* m_pTR;

  CPDF_TransferFunc* m_pTransferFunc;

  CFX_Matrix m_Matrix;

  int m_RenderIntent;

  FX_BOOL m_StrokeAdjust;

  FX_BOOL m_AlphaSource;

  FX_BOOL m_TextKnockout;

  FX_BOOL m_StrokeOP;

  FX_BOOL m_FillOP;

  int m_OPMode;

  CPDF_Object* m_pBG;

  CPDF_Object* m_pUCR;

  CPDF_Object* m_pHT;

  FX_FLOAT m_Flatness;

  FX_FLOAT m_Smoothness;
};
class CPDF_GeneralState : public CFX_CountRef<CPDF_GeneralStateData> {
 public:
  void SetRenderIntent(const CFX_ByteString& ri);

  int GetBlendType() const {
    return m_pObject ? m_pObject->m_BlendType : FXDIB_BLEND_NORMAL;
  }

  int GetAlpha(FX_BOOL bStroke) const {
    return m_pObject ? FXSYS_round((bStroke ? m_pObject->m_StrokeAlpha
                                            : m_pObject->m_FillAlpha) *
                                   255)
                     : 255;
  }
};
class CPDF_ContentMarkItem {
 public:
  typedef enum { None, PropertiesDict, DirectDict, MCID } ParamType;

  CPDF_ContentMarkItem();

  CPDF_ContentMarkItem(const CPDF_ContentMarkItem& src);

  ~CPDF_ContentMarkItem();

  inline const CFX_ByteString& GetName() const { return m_MarkName; }

  inline ParamType GetParamType() const { return m_ParamType; }

  inline void* GetParam() const { return m_pParam; }

  inline FX_BOOL HasMCID() const;

  inline void SetName(const CFX_ByteString& name) { m_MarkName = name; }

  inline void SetParam(ParamType type, void* param) {
    m_ParamType = type;
    m_pParam = param;
  }

 private:
  CFX_ByteString m_MarkName;

  ParamType m_ParamType;

  void* m_pParam;
};
class CPDF_ContentMarkData {
 public:
  CPDF_ContentMarkData() {}

  CPDF_ContentMarkData(const CPDF_ContentMarkData& src);

  inline int CountItems() const { return m_Marks.GetSize(); }

  inline CPDF_ContentMarkItem& GetItem(int index) const {
    return m_Marks[index];
  }

  int GetMCID() const;

  void AddMark(const CFX_ByteString& name,
               CPDF_Dictionary* pDict,
               FX_BOOL bDictNeedClone);

  void DeleteLastMark();

 private:
  CFX_ObjectArray<CPDF_ContentMarkItem> m_Marks;
};
class CPDF_ContentMark : public CFX_CountRef<CPDF_ContentMarkData> {
 public:
  int GetMCID() const { return m_pObject ? m_pObject->GetMCID() : -1; }

  FX_BOOL HasMark(const CFX_ByteStringC& mark) const;

  FX_BOOL LookupMark(const CFX_ByteStringC& mark,
                     CPDF_Dictionary*& pDict) const;
};

#define PDFPAGE_TEXT 1
#define PDFPAGE_PATH 2
#define PDFPAGE_IMAGE 3
#define PDFPAGE_SHADING 4
#define PDFPAGE_FORM 5

class CPDF_GraphicStates {
 public:
  void CopyStates(const CPDF_GraphicStates& src);

  void DefaultStates();

  CPDF_ClipPath m_ClipPath;

  CPDF_GraphState m_GraphState;

  CPDF_ColorState m_ColorState;

  CPDF_TextState m_TextState;

  CPDF_GeneralState m_GeneralState;
};

class CPDF_PageObject : public CPDF_GraphicStates {
 public:
  static CPDF_PageObject* Create(int type);
  virtual ~CPDF_PageObject();

  CPDF_PageObject* Clone() const;

  void Copy(const CPDF_PageObject* pSrcObject);

  virtual void Transform(const CFX_AffineMatrix& matrix) = 0;

  void RemoveClipPath();

  void AppendClipPath(CPDF_Path path, int type, FX_BOOL bAutoMerge);

  void CopyClipPath(CPDF_PageObject* pObj);

  void TransformClipPath(CFX_AffineMatrix& matrix);

  void TransformGeneralState(CFX_AffineMatrix& matrix);

  void SetColorState(CPDF_ColorState state) { m_ColorState = state; }

  FX_RECT GetBBox(const CFX_AffineMatrix* pMatrix) const;

  int m_Type;

  FX_FLOAT m_Left;

  FX_FLOAT m_Right;

  FX_FLOAT m_Top;

  FX_FLOAT m_Bottom;

  CPDF_ContentMark m_ContentMark;

 protected:
  virtual void CopyData(const CPDF_PageObject* pSrcObject) = 0;

  void RecalcBBox();

  CPDF_PageObject() {}
};

struct CPDF_TextObjectItem {
  FX_DWORD m_CharCode;
  FX_FLOAT m_OriginX;
  FX_FLOAT m_OriginY;
};

class CPDF_TextObject : public CPDF_PageObject {
 public:
  CPDF_TextObject();
  ~CPDF_TextObject() override;

  int CountItems() const { return m_nChars; }

  void GetItemInfo(int index, CPDF_TextObjectItem* pInfo) const;

  int CountChars() const;

  void GetCharInfo(int index, FX_DWORD& charcode, FX_FLOAT& kerning) const;
  void GetCharInfo(int index, CPDF_TextObjectItem* pInfo) const;

  void GetCharRect(int index, CFX_FloatRect& rect) const;

  FX_FLOAT GetCharWidth(FX_DWORD charcode) const;
  FX_FLOAT GetSpaceCharWidth() const;

  FX_FLOAT GetPosX() const { return m_PosX; }

  FX_FLOAT GetPosY() const { return m_PosY; }

  void GetTextMatrix(CFX_AffineMatrix* pMatrix) const;

  CPDF_Font* GetFont() const { return m_TextState.GetFont(); }

  FX_FLOAT GetFontSize() const { return m_TextState.GetFontSize(); }

  void SetEmpty();

  void SetText(const CFX_ByteString& text);

  void SetText(CFX_ByteString* pStrs, FX_FLOAT* pKerning, int nSegs);

  void SetText(int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pKernings);

  void SetPosition(FX_FLOAT x, FX_FLOAT y);

  void SetTextState(CPDF_TextState TextState);

  // CPDF_PageObject:
  void Transform(const CFX_AffineMatrix& matrix) override;

  void CalcCharPos(FX_FLOAT* pPosArray) const;

  void SetData(int nChars,
               FX_DWORD* pCharCodes,
               FX_FLOAT* pCharPos,
               FX_FLOAT x,
               FX_FLOAT y);

  void GetData(int& nChars, FX_DWORD*& pCharCodes, FX_FLOAT*& pCharPos) {
    nChars = m_nChars;
    pCharCodes = m_pCharCodes;
    pCharPos = m_pCharPos;
  }

  void RecalcPositionData() { CalcPositionData(nullptr, nullptr, 1); }

 protected:
  friend class CPDF_RenderStatus;
  friend class CPDF_StreamContentParser;
  friend class CPDF_TextRenderer;
  friend class CTextPage;

  // CPDF_PageObject:
  void CopyData(const CPDF_PageObject* pSrcObject) override;

  void SetSegments(const CFX_ByteString* pStrs, FX_FLOAT* pKerning, int nSegs);

  void CalcPositionData(FX_FLOAT* pTextAdvanceX,
                        FX_FLOAT* pTextAdvanceY,
                        FX_FLOAT horz_scale,
                        int level = 0);

  FX_FLOAT m_PosX;
  FX_FLOAT m_PosY;

  int m_nChars;

  FX_DWORD* m_pCharCodes;

  FX_FLOAT* m_pCharPos;
};

class CPDF_PathObject : public CPDF_PageObject {
 public:
  CPDF_PathObject() { m_Type = PDFPAGE_PATH; }

  virtual ~CPDF_PathObject() {}
  void Transform(const CFX_AffineMatrix& maxtrix) override;

  void SetGraphState(CPDF_GraphState GraphState);

  CPDF_Path m_Path;

  int m_FillType;

  FX_BOOL m_bStroke;

  CFX_AffineMatrix m_Matrix;

  void CalcBoundingBox();

 protected:
  void CopyData(const CPDF_PageObject* pSrcObject) override;
};

class CPDF_ImageObject : public CPDF_PageObject {
 public:
  CPDF_ImageObject();

  virtual ~CPDF_ImageObject();
  void Transform(const CFX_AffineMatrix& matrix) override;

  CPDF_Image* m_pImage;

  CFX_AffineMatrix m_Matrix;

  void CalcBoundingBox();

 private:
  void CopyData(const CPDF_PageObject* pSrcObject) override;
};

class CPDF_ShadingObject : public CPDF_PageObject {
 public:
  CPDF_ShadingObject();

  virtual ~CPDF_ShadingObject();

  CPDF_ShadingPattern* m_pShading;

  CFX_AffineMatrix m_Matrix;

  void Transform(const CFX_AffineMatrix& matrix) override;

  void CalcBoundingBox();

 protected:
  void CopyData(const CPDF_PageObject* pSrcObject) override;
};

class CPDF_FormObject : public CPDF_PageObject {
 public:
  CPDF_FormObject() {
    m_Type = PDFPAGE_FORM;
    m_pForm = NULL;
  }

  virtual ~CPDF_FormObject();
  void Transform(const CFX_AffineMatrix& matrix) override;

  CPDF_Form* m_pForm;

  CFX_AffineMatrix m_FormMatrix;

  void CalcBoundingBox();

 protected:
  void CopyData(const CPDF_PageObject* pSrcObject) override;
};

#endif  // CORE_INCLUDE_FPDFAPI_FPDF_PAGEOBJ_H_
