1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #ifndef CORE_INCLUDE_FPDFAPI_FPDF_PAGEOBJ_H_
8 #define CORE_INCLUDE_FPDFAPI_FPDF_PAGEOBJ_H_
9 
10 #include "core/include/fxge/fx_ge.h"
11 #include "fpdf_resource.h"
12 
13 class CPDF_ClipPath;
14 class CPDF_ClipPathData;
15 class CPDF_ColorState;
16 class CPDF_ColorStateData;
17 class CPDF_ContentMark;
18 class CPDF_ContentMarkItem;
19 class CPDF_FormObject;
20 class CPDF_GeneralState;
21 class CPDF_GeneralStateData;
22 class CPDF_GraphicStates;
23 class CPDF_GraphState;
24 class CPDF_ImageObject;
25 class CPDF_PageObject;
26 class CPDF_Path;
27 class CPDF_PathObject;
28 class CPDF_ShadingObject;
29 class CPDF_TextObject;
30 class CPDF_TextState;
31 class CPDF_TextStateData;
32 class CPDF_TransferFunc;
33 
34 typedef CFX_PathData CPDF_PathData;
35 
36 class CPDF_Path : public CFX_CountRef<CFX_PathData> {
37  public:
GetPointCount()38   int GetPointCount() { return m_pObject->m_PointCount; }
39 
GetFlag(int index)40   int GetFlag(int index) { return m_pObject->m_pPoints[index].m_Flag; }
41 
GetPointX(int index)42   FX_FLOAT GetPointX(int index) { return m_pObject->m_pPoints[index].m_PointX; }
43 
GetPointY(int index)44   FX_FLOAT GetPointY(int index) { return m_pObject->m_pPoints[index].m_PointY; }
45 
GetPoints()46   FX_PATHPOINT* GetPoints() { return m_pObject->m_pPoints; }
47 
GetBoundingBox()48   CFX_FloatRect GetBoundingBox() const { return m_pObject->GetBoundingBox(); }
49 
GetBoundingBox(FX_FLOAT line_width,FX_FLOAT miter_limit)50   CFX_FloatRect GetBoundingBox(FX_FLOAT line_width,
51                                FX_FLOAT miter_limit) const {
52     return m_pObject->GetBoundingBox(line_width, miter_limit);
53   }
54 
Transform(const CFX_Matrix * pMatrix)55   void Transform(const CFX_Matrix* pMatrix) { GetModify()->Transform(pMatrix); }
56 
Append(CPDF_Path src,const CFX_Matrix * pMatrix)57   void Append(CPDF_Path src, const CFX_Matrix* pMatrix) {
58     m_pObject->Append(src.m_pObject, pMatrix);
59   }
60 
AppendRect(FX_FLOAT left,FX_FLOAT bottom,FX_FLOAT right,FX_FLOAT top)61   void AppendRect(FX_FLOAT left,
62                   FX_FLOAT bottom,
63                   FX_FLOAT right,
64                   FX_FLOAT top) {
65     m_pObject->AppendRect(left, bottom, right, top);
66   }
67 
IsRect()68   FX_BOOL IsRect() const { return m_pObject->IsRect(); }
69 };
70 class CPDF_ClipPathData {
71  public:
72   CPDF_ClipPathData();
73   CPDF_ClipPathData(const CPDF_ClipPathData&);
74   ~CPDF_ClipPathData();
75 
76   void SetCount(int path_count, int text_count);
77 
78  public:
79   int m_PathCount;
80 
81   CPDF_Path* m_pPathList;
82 
83   uint8_t* m_pTypeList;
84 
85   int m_TextCount;
86 
87   CPDF_TextObject** m_pTextList;
88 };
89 
90 class CPDF_ClipPath : public CFX_CountRef<CPDF_ClipPathData> {
91  public:
GetPathCount()92   FX_DWORD GetPathCount() const { return m_pObject->m_PathCount; }
93 
GetPath(int i)94   CPDF_Path GetPath(int i) const { return m_pObject->m_pPathList[i]; }
95 
GetClipType(int i)96   int GetClipType(int i) const { return m_pObject->m_pTypeList[i]; }
97 
GetTextCount()98   FX_DWORD GetTextCount() const { return m_pObject->m_TextCount; }
99 
GetText(int i)100   CPDF_TextObject* GetText(int i) const { return m_pObject->m_pTextList[i]; }
101 
102   CFX_FloatRect GetClipBox() const;
103 
104   void AppendPath(CPDF_Path path, int type, FX_BOOL bAutoMerge);
105 
106   void DeletePath(int layer_index);
107 
108   void AppendTexts(CPDF_TextObject** pTexts, int count);
109 
110   void Transform(const CFX_Matrix& matrix);
111 };
112 class CPDF_ColorStateData {
113  public:
CPDF_ColorStateData()114   CPDF_ColorStateData() : m_FillRGB(0), m_StrokeRGB(0) {}
115 
116   CPDF_ColorStateData(const CPDF_ColorStateData& src);
117 
118   void Default();
119 
120   CPDF_Color m_FillColor;
121 
122   FX_DWORD m_FillRGB;
123 
124   CPDF_Color m_StrokeColor;
125 
126   FX_DWORD m_StrokeRGB;
127 };
128 class CPDF_ColorState : public CFX_CountRef<CPDF_ColorStateData> {
129  public:
GetFillColor()130   CPDF_Color* GetFillColor() const {
131     return m_pObject ? &m_pObject->m_FillColor : NULL;
132   }
133 
GetStrokeColor()134   CPDF_Color* GetStrokeColor() const {
135     return m_pObject ? &m_pObject->m_StrokeColor : NULL;
136   }
137 
138   void SetFillColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues);
139 
140   void SetStrokeColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues);
141 
142   void SetFillPattern(CPDF_Pattern* pattern, FX_FLOAT* pValue, int nValues);
143 
144   void SetStrokePattern(CPDF_Pattern* pattern, FX_FLOAT* pValue, int nValues);
145 
146  private:
147   void SetColor(CPDF_Color& color,
148                 FX_DWORD& rgb,
149                 CPDF_ColorSpace* pCS,
150                 FX_FLOAT* pValue,
151                 int nValues);
152 };
153 typedef CFX_GraphStateData CPDF_GraphStateData;
154 class CPDF_GraphState : public CFX_CountRef<CFX_GraphStateData> {
155  public:
156 };
157 class CPDF_TextStateData {
158  public:
159   CPDF_TextStateData();
160 
161   CPDF_TextStateData(const CPDF_TextStateData& src);
162 
163   ~CPDF_TextStateData();
164 
165   CPDF_Font* m_pFont;
166 
167   CPDF_Document* m_pDocument;
168 
169   FX_FLOAT m_FontSize;
170 
171   FX_FLOAT m_CharSpace;
172 
173   FX_FLOAT m_WordSpace;
174 
175   FX_FLOAT m_Matrix[4];
176 
177   int m_TextMode;
178 
179   FX_FLOAT m_CTM[4];
180 };
181 class CPDF_TextState : public CFX_CountRef<CPDF_TextStateData> {
182  public:
GetFont()183   CPDF_Font* GetFont() const { return m_pObject->m_pFont; }
184 
185   void SetFont(CPDF_Font* pFont);
186 
GetFontSize()187   FX_FLOAT GetFontSize() const { return m_pObject->m_FontSize; }
188 
GetMatrix()189   FX_FLOAT* GetMatrix() const { return m_pObject->m_Matrix; }
190 
191   FX_FLOAT GetFontSizeV() const;
192 
193   FX_FLOAT GetFontSizeH() const;
194 
195   FX_FLOAT GetBaselineAngle() const;
196 
197   FX_FLOAT GetShearAngle() const;
198 };
199 
200 class CPDF_GeneralStateData {
201  public:
202   CPDF_GeneralStateData();
203 
204   CPDF_GeneralStateData(const CPDF_GeneralStateData& src);
205   ~CPDF_GeneralStateData();
206 
207   void SetBlendMode(const CFX_ByteStringC& blend_mode);
208 
209   char m_BlendMode[16];
210 
211   int m_BlendType;
212 
213   CPDF_Object* m_pSoftMask;
214 
215   FX_FLOAT m_SMaskMatrix[6];
216 
217   FX_FLOAT m_StrokeAlpha;
218 
219   FX_FLOAT m_FillAlpha;
220 
221   CPDF_Object* m_pTR;
222 
223   CPDF_TransferFunc* m_pTransferFunc;
224 
225   CFX_Matrix m_Matrix;
226 
227   int m_RenderIntent;
228 
229   FX_BOOL m_StrokeAdjust;
230 
231   FX_BOOL m_AlphaSource;
232 
233   FX_BOOL m_TextKnockout;
234 
235   FX_BOOL m_StrokeOP;
236 
237   FX_BOOL m_FillOP;
238 
239   int m_OPMode;
240 
241   CPDF_Object* m_pBG;
242 
243   CPDF_Object* m_pUCR;
244 
245   CPDF_Object* m_pHT;
246 
247   FX_FLOAT m_Flatness;
248 
249   FX_FLOAT m_Smoothness;
250 };
251 class CPDF_GeneralState : public CFX_CountRef<CPDF_GeneralStateData> {
252  public:
253   void SetRenderIntent(const CFX_ByteString& ri);
254 
GetBlendType()255   int GetBlendType() const {
256     return m_pObject ? m_pObject->m_BlendType : FXDIB_BLEND_NORMAL;
257   }
258 
GetAlpha(FX_BOOL bStroke)259   int GetAlpha(FX_BOOL bStroke) const {
260     return m_pObject ? FXSYS_round((bStroke ? m_pObject->m_StrokeAlpha
261                                             : m_pObject->m_FillAlpha) *
262                                    255)
263                      : 255;
264   }
265 };
266 class CPDF_ContentMarkItem {
267  public:
268   typedef enum { None, PropertiesDict, DirectDict, MCID } ParamType;
269 
270   CPDF_ContentMarkItem();
271 
272   CPDF_ContentMarkItem(const CPDF_ContentMarkItem& src);
273 
274   ~CPDF_ContentMarkItem();
275 
GetName()276   inline const CFX_ByteString& GetName() const { return m_MarkName; }
277 
GetParamType()278   inline ParamType GetParamType() const { return m_ParamType; }
279 
GetParam()280   inline void* GetParam() const { return m_pParam; }
281 
282   inline FX_BOOL HasMCID() const;
283 
SetName(const CFX_ByteString & name)284   inline void SetName(const CFX_ByteString& name) { m_MarkName = name; }
285 
SetParam(ParamType type,void * param)286   inline void SetParam(ParamType type, void* param) {
287     m_ParamType = type;
288     m_pParam = param;
289   }
290 
291  private:
292   CFX_ByteString m_MarkName;
293 
294   ParamType m_ParamType;
295 
296   void* m_pParam;
297 };
298 class CPDF_ContentMarkData {
299  public:
CPDF_ContentMarkData()300   CPDF_ContentMarkData() {}
301 
302   CPDF_ContentMarkData(const CPDF_ContentMarkData& src);
303 
CountItems()304   inline int CountItems() const { return m_Marks.GetSize(); }
305 
GetItem(int index)306   inline CPDF_ContentMarkItem& GetItem(int index) const {
307     return m_Marks[index];
308   }
309 
310   int GetMCID() const;
311 
312   void AddMark(const CFX_ByteString& name,
313                CPDF_Dictionary* pDict,
314                FX_BOOL bDictNeedClone);
315 
316   void DeleteLastMark();
317 
318  private:
319   CFX_ObjectArray<CPDF_ContentMarkItem> m_Marks;
320 };
321 class CPDF_ContentMark : public CFX_CountRef<CPDF_ContentMarkData> {
322  public:
GetMCID()323   int GetMCID() const { return m_pObject ? m_pObject->GetMCID() : -1; }
324 
325   FX_BOOL HasMark(const CFX_ByteStringC& mark) const;
326 
327   FX_BOOL LookupMark(const CFX_ByteStringC& mark,
328                      CPDF_Dictionary*& pDict) const;
329 };
330 
331 #define PDFPAGE_TEXT 1
332 #define PDFPAGE_PATH 2
333 #define PDFPAGE_IMAGE 3
334 #define PDFPAGE_SHADING 4
335 #define PDFPAGE_FORM 5
336 
337 class CPDF_GraphicStates {
338  public:
339   void CopyStates(const CPDF_GraphicStates& src);
340 
341   void DefaultStates();
342 
343   CPDF_ClipPath m_ClipPath;
344 
345   CPDF_GraphState m_GraphState;
346 
347   CPDF_ColorState m_ColorState;
348 
349   CPDF_TextState m_TextState;
350 
351   CPDF_GeneralState m_GeneralState;
352 };
353 
354 class CPDF_PageObject : public CPDF_GraphicStates {
355  public:
356   static CPDF_PageObject* Create(int type);
357   virtual ~CPDF_PageObject();
358 
359   CPDF_PageObject* Clone() const;
360 
361   void Copy(const CPDF_PageObject* pSrcObject);
362 
363   virtual void Transform(const CFX_Matrix& matrix) = 0;
364 
365   void RemoveClipPath();
366 
367   void AppendClipPath(CPDF_Path path, int type, FX_BOOL bAutoMerge);
368 
369   void CopyClipPath(CPDF_PageObject* pObj);
370 
371   void TransformClipPath(CFX_Matrix& matrix);
372 
373   void TransformGeneralState(CFX_Matrix& matrix);
374 
SetColorState(CPDF_ColorState state)375   void SetColorState(CPDF_ColorState state) { m_ColorState = state; }
376 
377   FX_RECT GetBBox(const CFX_Matrix* pMatrix) const;
378 
379   int m_Type;
380 
381   FX_FLOAT m_Left;
382 
383   FX_FLOAT m_Right;
384 
385   FX_FLOAT m_Top;
386 
387   FX_FLOAT m_Bottom;
388 
389   CPDF_ContentMark m_ContentMark;
390 
391  protected:
392   virtual void CopyData(const CPDF_PageObject* pSrcObject) = 0;
393 
394   void RecalcBBox();
395 
CPDF_PageObject()396   CPDF_PageObject() {}
397 };
398 
399 struct CPDF_TextObjectItem {
400   FX_DWORD m_CharCode;
401   FX_FLOAT m_OriginX;
402   FX_FLOAT m_OriginY;
403 };
404 
405 class CPDF_TextObject : public CPDF_PageObject {
406  public:
407   CPDF_TextObject();
408   ~CPDF_TextObject() override;
409 
CountItems()410   int CountItems() const { return m_nChars; }
411 
412   void GetItemInfo(int index, CPDF_TextObjectItem* pInfo) const;
413 
414   int CountChars() const;
415 
416   void GetCharInfo(int index, FX_DWORD& charcode, FX_FLOAT& kerning) const;
417   void GetCharInfo(int index, CPDF_TextObjectItem* pInfo) const;
418 
419   void GetCharRect(int index, CFX_FloatRect& rect) const;
420 
421   FX_FLOAT GetCharWidth(FX_DWORD charcode) const;
422   FX_FLOAT GetSpaceCharWidth() const;
423 
GetPosX()424   FX_FLOAT GetPosX() const { return m_PosX; }
425 
GetPosY()426   FX_FLOAT GetPosY() const { return m_PosY; }
427 
428   void GetTextMatrix(CFX_Matrix* pMatrix) const;
429 
GetFont()430   CPDF_Font* GetFont() const { return m_TextState.GetFont(); }
431 
GetFontSize()432   FX_FLOAT GetFontSize() const { return m_TextState.GetFontSize(); }
433 
434   void SetEmpty();
435 
436   void SetText(const CFX_ByteString& text);
437 
438   void SetText(CFX_ByteString* pStrs, FX_FLOAT* pKerning, int nSegs);
439 
440   void SetText(int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pKernings);
441 
442   void SetPosition(FX_FLOAT x, FX_FLOAT y);
443 
444   void SetTextState(CPDF_TextState TextState);
445 
446   // CPDF_PageObject:
447   void Transform(const CFX_Matrix& matrix) override;
448 
449   void CalcCharPos(FX_FLOAT* pPosArray) const;
450 
451   void SetData(int nChars,
452                FX_DWORD* pCharCodes,
453                FX_FLOAT* pCharPos,
454                FX_FLOAT x,
455                FX_FLOAT y);
456 
GetData(int & nChars,FX_DWORD * & pCharCodes,FX_FLOAT * & pCharPos)457   void GetData(int& nChars, FX_DWORD*& pCharCodes, FX_FLOAT*& pCharPos) {
458     nChars = m_nChars;
459     pCharCodes = m_pCharCodes;
460     pCharPos = m_pCharPos;
461   }
462 
RecalcPositionData()463   void RecalcPositionData() { CalcPositionData(nullptr, nullptr, 1); }
464 
465  protected:
466   friend class CPDF_RenderStatus;
467   friend class CPDF_StreamContentParser;
468   friend class CPDF_TextRenderer;
469   friend class CTextPage;
470 
471   // CPDF_PageObject:
472   void CopyData(const CPDF_PageObject* pSrcObject) override;
473 
474   void SetSegments(const CFX_ByteString* pStrs, FX_FLOAT* pKerning, int nSegs);
475 
476   void CalcPositionData(FX_FLOAT* pTextAdvanceX,
477                         FX_FLOAT* pTextAdvanceY,
478                         FX_FLOAT horz_scale,
479                         int level = 0);
480 
481   FX_FLOAT m_PosX;
482   FX_FLOAT m_PosY;
483 
484   int m_nChars;
485 
486   FX_DWORD* m_pCharCodes;
487 
488   FX_FLOAT* m_pCharPos;
489 };
490 
491 class CPDF_PathObject : public CPDF_PageObject {
492  public:
CPDF_PathObject()493   CPDF_PathObject() { m_Type = PDFPAGE_PATH; }
~CPDF_PathObject()494   ~CPDF_PathObject() override {}
495 
496   void Transform(const CFX_Matrix& maxtrix) override;
497 
498   void SetGraphState(CPDF_GraphState GraphState);
499 
500   void CalcBoundingBox();
501 
502   CPDF_Path m_Path;
503 
504   int m_FillType;
505 
506   FX_BOOL m_bStroke;
507 
508   CFX_Matrix m_Matrix;
509 
510  protected:
511   void CopyData(const CPDF_PageObject* pSrcObject) override;
512 };
513 
514 class CPDF_ImageObject : public CPDF_PageObject {
515  public:
516   CPDF_ImageObject();
517   ~CPDF_ImageObject() override;
518 
519   void Transform(const CFX_Matrix& matrix) override;
520 
521   CPDF_Image* m_pImage;
522 
523   CFX_Matrix m_Matrix;
524 
525   void CalcBoundingBox();
526 
527  private:
528   void CopyData(const CPDF_PageObject* pSrcObject) override;
529 };
530 
531 class CPDF_ShadingObject : public CPDF_PageObject {
532  public:
533   CPDF_ShadingObject();
534   ~CPDF_ShadingObject() override;
535 
536   CPDF_ShadingPattern* m_pShading;
537 
538   CFX_Matrix m_Matrix;
539 
540   void Transform(const CFX_Matrix& matrix) override;
541 
542   void CalcBoundingBox();
543 
544  protected:
545   void CopyData(const CPDF_PageObject* pSrcObject) override;
546 };
547 
548 class CPDF_FormObject : public CPDF_PageObject {
549  public:
CPDF_FormObject()550   CPDF_FormObject() {
551     m_Type = PDFPAGE_FORM;
552     m_pForm = NULL;
553   }
554   ~CPDF_FormObject() override;
555 
556   void Transform(const CFX_Matrix& matrix) override;
557 
558   CPDF_Form* m_pForm;
559 
560   CFX_Matrix m_FormMatrix;
561 
562   void CalcBoundingBox();
563 
564  protected:
565   void CopyData(const CPDF_PageObject* pSrcObject) override;
566 };
567 
568 #endif  // CORE_INCLUDE_FPDFAPI_FPDF_PAGEOBJ_H_
569