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 _FPDF_RENDER_
8#define _FPDF_RENDER_
9#ifndef _FPDF_PAGE_
10#include "fpdf_page.h"
11#endif
12#ifndef _FX_GE_H_
13#include "../fxge/fx_ge.h"
14#endif
15class CPDF_RenderContext;
16class CPDF_RenderOptions;
17class CPDF_ImageCache;
18class IPDF_OCContext;
19class CPDF_QuickStretcher;
20class CFX_PathData;
21class CFX_GraphStateData;
22class CFX_RenderDevice;
23class CPDF_TextObject;
24class CPDF_PathObject;
25class CPDF_ImageObject;
26class CPDF_ShadingObject;
27class CPDF_FormObject;
28class IPDF_OCContext
29{
30public:
31
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 : public CFX_Object
59{
60public:
61
62    CPDF_RenderOptions();
63
64    int				m_ColorMode;
65
66    FX_COLORREF		m_BackColor;
67
68    FX_COLORREF		m_ForeColor;
69
70    FX_DWORD		m_Flags;
71
72    int				m_Interpolation;
73
74    FX_DWORD		m_AddFlags;
75
76    IPDF_OCContext*	m_pOCContext;
77
78    FX_DWORD		m_dwLimitCacheSize;
79
80    int				m_HalftoneLimit;
81
82    FX_ARGB			TranslateColor(FX_ARGB argb) const;
83};
84class CPDF_RenderContext : public CFX_Object
85{
86public:
87
88    CPDF_RenderContext();
89
90    void			Create(CPDF_Page* pPage, FX_BOOL bFirstLayer = TRUE);
91
92    void			Create(CPDF_Document* pDoc = NULL, CPDF_PageRenderCache* pPageCache = NULL,
93                           CPDF_Dictionary* pPageResources = NULL, FX_BOOL bFirstLayer = TRUE);
94
95    ~CPDF_RenderContext();
96
97    void			Clear();
98
99    void			AppendObjectList(CPDF_PageObjects* pObjs, const CFX_AffineMatrix* pObject2Device);
100
101    void			SetBackground(class IPDF_BackgroundDraw* pBackground);
102
103    void			Render(CFX_RenderDevice* pDevice, const CPDF_RenderOptions* pOptions = NULL,
104                           const CFX_AffineMatrix* pFinalMatrix = NULL);
105
106    void			DrawObjectList(CFX_RenderDevice* pDevice, CPDF_PageObjects* pObjs,
107                                   const CFX_AffineMatrix* pObject2Device, const CPDF_RenderOptions* pOptions);
108
109    void			GetBackground(CFX_DIBitmap* pBuffer, const CPDF_PageObject* pObj,
110                                  const CPDF_RenderOptions* pOptions, CFX_AffineMatrix* pFinalMatrix);
111
112    CPDF_PageRenderCache*	GetPageCache() const
113    {
114        return m_pPageCache;
115    }
116
117
118
119    CPDF_Document*			m_pDocument;
120
121    CPDF_Dictionary*		m_pPageResources;
122
123    CPDF_PageRenderCache*	m_pPageCache;
124
125protected:
126
127    CFX_ArrayTemplate<struct _PDF_RenderItem>	m_ContentList;
128
129    IPDF_BackgroundDraw*	m_pBackgroundDraw;
130
131    FX_BOOL					m_bFirstLayer;
132
133    void			Render(CFX_RenderDevice* pDevice, const CPDF_PageObject* pStopObj,
134                           const CPDF_RenderOptions* pOptions, const CFX_AffineMatrix* pFinalMatrix);
135    friend class CPDF_RenderStatus;
136    friend class CPDF_ProgressiveRenderer;
137};
138class IPDF_BackgroundDraw
139{
140public:
141
142    virtual	void	OnDrawBackground(
143        CFX_RenderDevice* pBitmapDevice,
144        const CFX_AffineMatrix* pOriginal2Bitmap
145    ) = 0;
146};
147class CPDF_ProgressiveRenderer : public CFX_Object
148{
149public:
150
151    CPDF_ProgressiveRenderer();
152
153    ~CPDF_ProgressiveRenderer();
154
155    typedef enum {
156        Ready,
157        ToBeContinued,
158        Done,
159        Failed
160    } RenderStatus;
161
162    RenderStatus		GetStatus()
163    {
164        return m_Status;
165    }
166
167
168
169    void				Start(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice,
170                              const CPDF_RenderOptions* pOptions, class IFX_Pause* pPause, FX_BOOL bDropObjects = FALSE);
171
172    void				Continue(class IFX_Pause* pPause);
173
174
175    int					EstimateProgress();
176
177    void				Clear();
178protected:
179
180    RenderStatus		m_Status;
181
182    CPDF_RenderContext*	m_pContext;
183
184    CFX_RenderDevice*	m_pDevice;
185
186    const CPDF_RenderOptions*	m_pOptions;
187
188    FX_BOOL				m_bDropObjects;
189
190    class CPDF_RenderStatus*	m_pRenderer;
191
192    CFX_FloatRect		m_ClipRect;
193
194    FX_DWORD			m_LayerIndex;
195
196    FX_DWORD			m_ObjectIndex;
197
198    FX_POSITION			m_ObjectPos;
199
200    FX_POSITION			m_PrevLastPos;
201
202    void				RenderStep();
203};
204class CPDF_TextRenderer : public CFX_Object
205{
206public:
207
208    static void		DrawTextString(CFX_RenderDevice* pDevice, int left, int top,
209                                   CPDF_Font* pFont,
210                                   int height,
211                                   const CFX_ByteString& str,
212                                   FX_ARGB argb);
213
214    static void		DrawTextString(CFX_RenderDevice* pDevice, FX_FLOAT origin_x, FX_FLOAT origin_y,
215                                   CPDF_Font* pFont,
216                                   FX_FLOAT font_size,
217                                   const CFX_AffineMatrix* matrix,
218                                   const CFX_ByteString& str,
219                                   FX_ARGB fill_argb,
220                                   FX_ARGB stroke_argb = 0,
221                                   const CFX_GraphStateData* pGraphState = NULL,
222                                   const CPDF_RenderOptions* pOptions = NULL
223                               );
224
225    static FX_BOOL	DrawTextPath(CFX_RenderDevice* pDevice, int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos,
226                                 CPDF_Font* pFont, FX_FLOAT font_size,
227                                 const CFX_AffineMatrix* pText2User, const CFX_AffineMatrix* pUser2Device,
228                                 const CFX_GraphStateData* pGraphState,
229                                 FX_ARGB fill_argb, FX_ARGB stroke_argb, CFX_PathData* pClippingPath, int nFlag = 0);
230
231    static FX_BOOL	DrawNormalText(CFX_RenderDevice* pDevice, int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos,
232                                   CPDF_Font* pFont, FX_FLOAT font_size, const CFX_AffineMatrix* pText2Device,
233                                   FX_ARGB fill_argb, const CPDF_RenderOptions* pOptions);
234
235    static FX_BOOL	DrawType3Text(CFX_RenderDevice* pDevice, int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos,
236                                  CPDF_Font* pFont, FX_FLOAT font_size, const CFX_AffineMatrix* pText2Device,
237                                  FX_ARGB fill_argb);
238};
239class IPDF_PageImageCache
240{
241public:
242
243    static IPDF_PageImageCache* Create();
244
245    virtual ~IPDF_PageImageCache() {}
246
247    virtual void		OutputPage(CFX_RenderDevice* pDevice, CPDF_Page* pPage,
248                                   int pos_x, int pos_y, int size_x, int size_y, int rotate) = 0;
249
250    virtual void		SetCacheLimit(FX_DWORD limit) = 0;
251};
252class CPDF_PageRenderCache : public CFX_Object
253{
254public:
255    CPDF_PageRenderCache(CPDF_Page* pPage)
256    {
257        m_pPage = pPage;
258        m_nTimeCount = 0;
259        m_nCacheSize = 0;
260        m_pCurImageCache = NULL;
261        m_bCurFindCache = FALSE;
262        m_pCurImageCaches = NULL;
263    }
264    ~CPDF_PageRenderCache()
265    {
266        ClearAll();
267    }
268    void				ClearAll();
269    void				ClearImageData();
270
271    FX_DWORD			EstimateSize();
272    void				CacheOptimization(FX_INT32 dwLimitCacheSize);
273    FX_DWORD			GetCachedSize(CPDF_Stream* pStream) const;
274    FX_DWORD			GetTimeCount() const
275    {
276        return m_nTimeCount;
277    }
278    void				SetTimeCount(FX_DWORD dwTimeCount)
279    {
280        m_nTimeCount = dwTimeCount;
281    }
282
283    void				GetCachedBitmap(CPDF_Stream* pStream, CFX_DIBSource*& pBitmap, CFX_DIBSource*& pMask, FX_DWORD& MatteColor,
284                                        FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0, FX_BOOL bLoadMask = FALSE,
285                                        CPDF_RenderStatus* pRenderStatus = NULL, FX_INT32 downsampleWidth = 0, FX_INT32 downsampleHeight = 0);
286
287    void				ResetBitmap(CPDF_Stream* pStream, const CFX_DIBitmap* pBitmap);
288    void				ClearImageCache(CPDF_Stream* pStream);
289    CPDF_Page*			GetPage()
290    {
291        return m_pPage;
292    }
293    CFX_MapPtrToPtr		m_ImageCaches;
294public:
295    FX_BOOL				StartGetCachedBitmap(CPDF_Stream* pStream, FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0,
296            FX_BOOL bLoadMask = FALSE, CPDF_RenderStatus* pRenderStatus = NULL,
297            FX_INT32 downsampleWidth = 0, FX_INT32 downsampleHeight = 0);
298
299    FX_BOOL				Continue(IFX_Pause* pPause);
300    CPDF_ImageCache*	m_pCurImageCache;
301    CFX_PtrArray*       m_pCurImageCaches;
302protected:
303    friend class		CPDF_Page;
304    CPDF_Page*			m_pPage;
305
306    FX_DWORD			m_nTimeCount;
307    FX_DWORD			m_nCacheSize;
308    FX_BOOL				m_bCurFindCache;
309};
310class CPDF_RenderConfig : public CFX_Object
311{
312public:
313    CPDF_RenderConfig();
314    ~CPDF_RenderConfig();
315    int					m_HalftoneLimit;
316    int					m_RenderStepLimit;
317};
318#endif
319