// 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/fpdfapi/fpdf_resource.h"
#include "core/include/fxge/fx_ge.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:
  enum ParamType { None, PropertiesDict, DirectDict };

  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 CPDF_Dictionary* 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, CPDF_Dictionary* param) {
    m_ParamType = type;
    m_pParam = param;
  }

 private:
  CFX_ByteString m_MarkName;

  ParamType m_ParamType;

  CPDF_Dictionary* 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;
};

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:
  enum Type {
    TEXT = 1,
    PATH,
    IMAGE,
    SHADING,
    FORM,
  };

  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;

  const Type 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(Type type) : m_Type(type) {}
};

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;

  // 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() : CPDF_PageObject(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() : CPDF_PageObject(FORM), m_pForm(nullptr) {}
  ~CPDF_FormObject() override;

  void Transform(const CFX_Matrix& matrix) override;
  void CalcBoundingBox();

  CPDF_Form* m_pForm;
  CFX_Matrix m_FormMatrix;

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

#endif  // CORE_INCLUDE_FPDFAPI_FPDF_PAGEOBJ_H_
