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