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
16class CFX_GraphStateData;
17class CFX_PathData;
18class CFX_RenderDevice;
19class CPDF_FormObject;
20class CPDF_ImageCacheEntry;
21class CPDF_ImageObject;
22class CPDF_PathObject;
23class CPDF_RenderContext;
24class CPDF_RenderOptions;
25class CPDF_RenderStatus;
26class CPDF_ShadingObject;
27class CPDF_TextObject;
28class IFX_Pause;
29
30class IPDF_OCContext {
31 public:
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
58class 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};
82class 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
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
123class 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
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
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
162class 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};
217class CPDF_PageRenderCache {
218 public:
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);
230  FX_DWORD GetTimeCount() const { return m_nTimeCount; }
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);
246  CPDF_Page* GetPage() const { return m_pPage; }
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};
270class CPDF_RenderConfig {
271 public:
272  CPDF_RenderConfig();
273  ~CPDF_RenderConfig();
274  int m_HalftoneLimit;
275  int m_RenderStepLimit;
276};
277
278FX_BOOL IsAvailableMatrix(const CFX_Matrix& matrix);
279
280#endif  // CORE_INCLUDE_FPDFAPI_FPDF_RENDER_H_
281