// 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 "core/include/fxge/fx_ge.h"
#include "fpdf_resource.h"

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

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_Matrix* pMatrix) { GetModify()->Transform(pMatrix); }

  void Append(CPDF_Path src, const CFX_Matrix* 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_Matrix& 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_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_Matrix& matrix) = 0;

  void RemoveClipPath();

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

  void CopyClipPath(CPDF_PageObject* pObj);

  void TransformClipPath(CFX_Matrix& matrix);

  void TransformGeneralState(CFX_Matrix& matrix);

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

  FX_RECT GetBBox(const CFX_Matrix* 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_Matrix* 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_Matrix& 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; }
  ~CPDF_PathObject() override {}

  void Transform(const CFX_Matrix& maxtrix) override;

  void SetGraphState(CPDF_GraphState GraphState);

  void CalcBoundingBox();

  CPDF_Path m_Path;

  int m_FillType;

  FX_BOOL m_bStroke;

  CFX_Matrix m_Matrix;

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

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

  void Transform(const CFX_Matrix& matrix) override;

  CPDF_Image* m_pImage;

  CFX_Matrix m_Matrix;

  void CalcBoundingBox();

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

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

  CPDF_ShadingPattern* m_pShading;

  CFX_Matrix m_Matrix;

  void Transform(const CFX_Matrix& 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;
  }
  ~CPDF_FormObject() override;

  void Transform(const CFX_Matrix& matrix) override;

  CPDF_Form* m_pForm;

  CFX_Matrix m_FormMatrix;

  void CalcBoundingBox();

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

#endif  // CORE_INCLUDE_FPDFAPI_FPDF_PAGEOBJ_H_
