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_RENDER_H_
8 #define CORE_INCLUDE_FPDFAPI_FPDF_RENDER_H_
9 
10 #include <map>
11 #include <memory>
12 
13 #include "core/include/fpdfapi/fpdf_page.h"
14 #include "core/include/fxge/fx_ge.h"
15 
16 class CFX_GraphStateData;
17 class CFX_PathData;
18 class CFX_RenderDevice;
19 class CPDF_FormObject;
20 class CPDF_ImageCacheEntry;
21 class CPDF_ImageObject;
22 class CPDF_PathObject;
23 class CPDF_RenderContext;
24 class CPDF_RenderOptions;
25 class CPDF_RenderStatus;
26 class CPDF_ShadingObject;
27 class CPDF_TextObject;
28 class IFX_Pause;
29 
30 class IPDF_OCContext {
31  public:
~IPDF_OCContext()32   virtual ~IPDF_OCContext() {}
33 
34   virtual FX_BOOL CheckOCGVisible(const CPDF_Dictionary* pOCG) = 0;
35 
36   FX_BOOL CheckObjectVisible(const CPDF_PageObject* pObj);
37 };
38 #define RENDER_COLOR_NORMAL 0
39 #define RENDER_COLOR_GRAY 1
40 #define RENDER_COLOR_TWOCOLOR 2
41 #define RENDER_COLOR_ALPHA 3
42 #define RENDER_CLEARTYPE 0x00000001
43 #define RENDER_PRINTGRAPHICTEXT 0x00000002
44 #define RENDER_FORCE_DOWNSAMPLE 0x00000004
45 #define RENDER_PRINTPREVIEW 0x00000008
46 #define RENDER_BGR_STRIPE 0x00000010
47 #define RENDER_NO_NATIVETEXT 0x00000020
48 #define RENDER_FORCE_HALFTONE 0x00000040
49 #define RENDER_RECT_AA 0x00000080
50 #define RENDER_FILL_FULLCOVER 0x00000100
51 #define RENDER_PRINTIMAGETEXT 0x00000200
52 #define RENDER_OVERPRINT 0x00000400
53 #define RENDER_THINLINE 0x00000800
54 #define RENDER_NOTEXTSMOOTH 0x10000000
55 #define RENDER_NOPATHSMOOTH 0x20000000
56 #define RENDER_NOIMAGESMOOTH 0x40000000
57 #define RENDER_LIMITEDIMAGECACHE 0x80000000
58 class CPDF_RenderOptions {
59  public:
60   CPDF_RenderOptions();
61 
62   int m_ColorMode;
63 
64   FX_COLORREF m_BackColor;
65 
66   FX_COLORREF m_ForeColor;
67 
68   FX_DWORD m_Flags;
69 
70   int m_Interpolation;
71 
72   FX_DWORD m_AddFlags;
73 
74   IPDF_OCContext* m_pOCContext;
75 
76   FX_DWORD m_dwLimitCacheSize;
77 
78   int m_HalftoneLimit;
79 
80   FX_ARGB TranslateColor(FX_ARGB argb) const;
81 };
82 class CPDF_RenderContext {
83  public:
84   explicit CPDF_RenderContext(CPDF_Page* pPage);
85   CPDF_RenderContext(CPDF_Document* pDoc, CPDF_PageRenderCache* pPageCache);
86   ~CPDF_RenderContext();
87 
88   void AppendObjectList(CPDF_PageObjects* pObjs,
89                         const CFX_Matrix* pObject2Device);
90 
91   void Render(CFX_RenderDevice* pDevice,
92               const CPDF_RenderOptions* pOptions = NULL,
93               const CFX_Matrix* pFinalMatrix = NULL);
94 
95   void DrawObjectList(CFX_RenderDevice* pDevice,
96                       CPDF_PageObjects* pObjs,
97                       const CFX_Matrix* pObject2Device,
98                       const CPDF_RenderOptions* pOptions);
99 
100   void GetBackground(CFX_DIBitmap* pBuffer,
101                      const CPDF_PageObject* pObj,
102                      const CPDF_RenderOptions* pOptions,
103                      CFX_Matrix* pFinalMatrix);
104 
GetPageCache()105   CPDF_PageRenderCache* GetPageCache() const { return m_pPageCache; }
106 
107  protected:
108   void Render(CFX_RenderDevice* pDevice,
109               const CPDF_PageObject* pStopObj,
110               const CPDF_RenderOptions* pOptions,
111               const CFX_Matrix* pFinalMatrix);
112 
113   CPDF_Document* const m_pDocument;
114   CPDF_Dictionary* m_pPageResources;
115   CPDF_PageRenderCache* m_pPageCache;
116   CFX_ArrayTemplate<struct _PDF_RenderItem> m_ContentList;
117   FX_BOOL m_bFirstLayer;
118 
119   friend class CPDF_RenderStatus;
120   friend class CPDF_ProgressiveRenderer;
121 };
122 
123 class CPDF_ProgressiveRenderer {
124  public:
125   // Must match FDF_RENDER_* definitions in public/fpdf_progressive.h, but
126   // cannot #include that header. fpdfsdk/src/fpdf_progressive.cpp has
127   // static_asserts to make sure the two sets of values match.
128   enum Status {
129     Ready,          // FPDF_RENDER_READER
130     ToBeContinued,  // FPDF_RENDER_TOBECOUNTINUED
131     Done,           // FPDF_RENDER_DONE
132     Failed          // FPDF_RENDER_FAILED
133   };
134 
ToFPDFStatus(Status status)135   static int ToFPDFStatus(Status status) { return static_cast<int>(status); }
136 
137   CPDF_ProgressiveRenderer(CPDF_RenderContext* pContext,
138                            CFX_RenderDevice* pDevice,
139                            const CPDF_RenderOptions* pOptions);
140   ~CPDF_ProgressiveRenderer();
141 
GetStatus()142   Status GetStatus() const { return m_Status; }
143   void Start(IFX_Pause* pPause);
144   void Continue(IFX_Pause* pPause);
145   int EstimateProgress();
146 
147  private:
148   void RenderStep();
149 
150   Status m_Status;
151   CPDF_RenderContext* const m_pContext;
152   CFX_RenderDevice* const m_pDevice;
153   const CPDF_RenderOptions* const m_pOptions;
154   std::unique_ptr<CPDF_RenderStatus> m_pRenderStatus;
155   CFX_FloatRect m_ClipRect;
156   FX_DWORD m_LayerIndex;
157   FX_DWORD m_ObjectIndex;
158   FX_POSITION m_ObjectPos;
159   FX_POSITION m_PrevLastPos;
160 };
161 
162 class CPDF_TextRenderer {
163  public:
164   static void DrawTextString(CFX_RenderDevice* pDevice,
165                              int left,
166                              int top,
167                              CPDF_Font* pFont,
168                              int height,
169                              const CFX_ByteString& str,
170                              FX_ARGB argb);
171 
172   static void DrawTextString(CFX_RenderDevice* pDevice,
173                              FX_FLOAT origin_x,
174                              FX_FLOAT origin_y,
175                              CPDF_Font* pFont,
176                              FX_FLOAT font_size,
177                              const CFX_Matrix* matrix,
178                              const CFX_ByteString& str,
179                              FX_ARGB fill_argb,
180                              FX_ARGB stroke_argb = 0,
181                              const CFX_GraphStateData* pGraphState = NULL,
182                              const CPDF_RenderOptions* pOptions = NULL);
183 
184   static FX_BOOL DrawTextPath(CFX_RenderDevice* pDevice,
185                               int nChars,
186                               FX_DWORD* pCharCodes,
187                               FX_FLOAT* pCharPos,
188                               CPDF_Font* pFont,
189                               FX_FLOAT font_size,
190                               const CFX_Matrix* pText2User,
191                               const CFX_Matrix* pUser2Device,
192                               const CFX_GraphStateData* pGraphState,
193                               FX_ARGB fill_argb,
194                               FX_ARGB stroke_argb,
195                               CFX_PathData* pClippingPath,
196                               int nFlag = 0);
197 
198   static FX_BOOL DrawNormalText(CFX_RenderDevice* pDevice,
199                                 int nChars,
200                                 FX_DWORD* pCharCodes,
201                                 FX_FLOAT* pCharPos,
202                                 CPDF_Font* pFont,
203                                 FX_FLOAT font_size,
204                                 const CFX_Matrix* pText2Device,
205                                 FX_ARGB fill_argb,
206                                 const CPDF_RenderOptions* pOptions);
207 
208   static FX_BOOL DrawType3Text(CFX_RenderDevice* pDevice,
209                                int nChars,
210                                FX_DWORD* pCharCodes,
211                                FX_FLOAT* pCharPos,
212                                CPDF_Font* pFont,
213                                FX_FLOAT font_size,
214                                const CFX_Matrix* pText2Device,
215                                FX_ARGB fill_argb);
216 };
217 class CPDF_PageRenderCache {
218  public:
CPDF_PageRenderCache(CPDF_Page * pPage)219   explicit CPDF_PageRenderCache(CPDF_Page* pPage)
220       : m_pPage(pPage),
221         m_pCurImageCacheEntry(nullptr),
222         m_nTimeCount(0),
223         m_nCacheSize(0),
224         m_bCurFindCache(FALSE) {}
225   ~CPDF_PageRenderCache();
226   void ClearImageData();
227 
228   FX_DWORD EstimateSize();
229   void CacheOptimization(int32_t dwLimitCacheSize);
GetTimeCount()230   FX_DWORD GetTimeCount() const { return m_nTimeCount; }
SetTimeCount(FX_DWORD dwTimeCount)231   void SetTimeCount(FX_DWORD dwTimeCount) { m_nTimeCount = dwTimeCount; }
232 
233   void GetCachedBitmap(CPDF_Stream* pStream,
234                        CFX_DIBSource*& pBitmap,
235                        CFX_DIBSource*& pMask,
236                        FX_DWORD& MatteColor,
237                        FX_BOOL bStdCS = FALSE,
238                        FX_DWORD GroupFamily = 0,
239                        FX_BOOL bLoadMask = FALSE,
240                        CPDF_RenderStatus* pRenderStatus = NULL,
241                        int32_t downsampleWidth = 0,
242                        int32_t downsampleHeight = 0);
243 
244   void ResetBitmap(CPDF_Stream* pStream, const CFX_DIBitmap* pBitmap);
245   void ClearImageCacheEntry(CPDF_Stream* pStream);
GetPage()246   CPDF_Page* GetPage() const { return m_pPage; }
GetCurImageCacheEntry()247   CPDF_ImageCacheEntry* GetCurImageCacheEntry() const {
248     return m_pCurImageCacheEntry;
249   }
250 
251   FX_BOOL StartGetCachedBitmap(CPDF_Stream* pStream,
252                                FX_BOOL bStdCS = FALSE,
253                                FX_DWORD GroupFamily = 0,
254                                FX_BOOL bLoadMask = FALSE,
255                                CPDF_RenderStatus* pRenderStatus = NULL,
256                                int32_t downsampleWidth = 0,
257                                int32_t downsampleHeight = 0);
258 
259   FX_BOOL Continue(IFX_Pause* pPause);
260 
261  protected:
262   friend class CPDF_Page;
263   CPDF_Page* const m_pPage;
264   CPDF_ImageCacheEntry* m_pCurImageCacheEntry;
265   std::map<CPDF_Stream*, CPDF_ImageCacheEntry*> m_ImageCache;
266   FX_DWORD m_nTimeCount;
267   FX_DWORD m_nCacheSize;
268   FX_BOOL m_bCurFindCache;
269 };
270 class CPDF_RenderConfig {
271  public:
272   CPDF_RenderConfig();
273   ~CPDF_RenderConfig();
274   int m_HalftoneLimit;
275   int m_RenderStepLimit;
276 };
277 
278 FX_BOOL IsAvailableMatrix(const CFX_Matrix& matrix);
279 
280 #endif  // CORE_INCLUDE_FPDFAPI_FPDF_RENDER_H_
281