Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(208)

Side by Side Diff: core/src/fpdfapi/fpdf_render/fpdf_render.cpp

Issue 1265503005: clang-format all pdfium code. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: sigh Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "../../../include/fpdfapi/fpdf_module.h" 7 #include "../../../include/fpdfapi/fpdf_module.h"
8 #include "../../../include/fpdfapi/fpdf_render.h" 8 #include "../../../include/fpdfapi/fpdf_render.h"
9 #include "../../../include/fxge/fx_ge.h" 9 #include "../../../include/fxge/fx_ge.h"
10 #include "../fpdf_page/pageint.h" 10 #include "../fpdf_page/pageint.h"
11 #include "render_int.h" 11 #include "render_int.h"
12 12
13 CPDF_DocRenderData::CPDF_DocRenderData(CPDF_Document* pPDFDoc) 13 CPDF_DocRenderData::CPDF_DocRenderData(CPDF_Document* pPDFDoc)
14 : m_pPDFDoc(pPDFDoc), 14 : m_pPDFDoc(pPDFDoc), m_pFontCache(new CFX_FontCache) {}
15 m_pFontCache(new CFX_FontCache) 15
16 { 16 CPDF_DocRenderData::~CPDF_DocRenderData() {
17 } 17 Clear(TRUE);
18 18 }
19 CPDF_DocRenderData::~CPDF_DocRenderData() 19
20 { 20 void CPDF_DocRenderData::Clear(FX_BOOL bRelease) {
21 Clear(TRUE); 21 for (auto it = m_Type3FaceMap.begin(); it != m_Type3FaceMap.end();) {
22 } 22 auto curr_it = it++;
23 23 CPDF_CountedObject<CPDF_Type3Cache>* cache = curr_it->second;
24 void CPDF_DocRenderData::Clear(FX_BOOL bRelease) 24 if (bRelease || cache->use_count() < 2) {
25 { 25 delete cache->get();
26 for (auto it = m_Type3FaceMap.begin(); it != m_Type3FaceMap.end();) { 26 delete cache;
27 auto curr_it = it++; 27 m_Type3FaceMap.erase(curr_it);
28 CPDF_CountedObject<CPDF_Type3Cache>* cache = curr_it->second; 28 }
29 if (bRelease || cache->use_count() < 2) { 29 }
30 delete cache->get(); 30
31 delete cache; 31 for (auto it = m_TransferFuncMap.begin(); it != m_TransferFuncMap.end();) {
32 m_Type3FaceMap.erase(curr_it); 32 auto curr_it = it++;
33 } 33 CPDF_CountedObject<CPDF_TransferFunc>* value = curr_it->second;
34 } 34 if (bRelease || value->use_count() < 2) {
35 35 delete value->get();
36 for (auto it = m_TransferFuncMap.begin(); it != m_TransferFuncMap.end();) { 36 delete value;
37 auto curr_it = it++; 37 m_TransferFuncMap.erase(curr_it);
38 CPDF_CountedObject<CPDF_TransferFunc>* value = curr_it->second; 38 }
39 if (bRelease || value->use_count() < 2) { 39 }
40 delete value->get(); 40
41 delete value; 41 if (m_pFontCache) {
42 m_TransferFuncMap.erase(curr_it); 42 if (bRelease) {
43 } 43 delete m_pFontCache;
44 } 44 m_pFontCache = NULL;
45
46 if (m_pFontCache) {
47 if (bRelease) {
48 delete m_pFontCache;
49 m_pFontCache = NULL;
50 } else {
51 m_pFontCache->FreeCache(FALSE);
52 }
53 }
54 }
55
56 CPDF_Type3Cache* CPDF_DocRenderData::GetCachedType3(CPDF_Type3Font* pFont)
57 {
58 CPDF_CountedObject<CPDF_Type3Cache>* pCache;
59 auto it = m_Type3FaceMap.find(pFont);
60 if (it == m_Type3FaceMap.end()) {
61 CPDF_Type3Cache* pType3 = new CPDF_Type3Cache(pFont);
62 pCache = new CPDF_CountedObject<CPDF_Type3Cache>(pType3);
63 m_Type3FaceMap[pFont] = pCache;
64 } else { 45 } else {
65 pCache = it->second; 46 m_pFontCache->FreeCache(FALSE);
66 } 47 }
67 return pCache->AddRef(); 48 }
68 } 49 }
69 50
70 void CPDF_DocRenderData::ReleaseCachedType3(CPDF_Type3Font* pFont) 51 CPDF_Type3Cache* CPDF_DocRenderData::GetCachedType3(CPDF_Type3Font* pFont) {
71 { 52 CPDF_CountedObject<CPDF_Type3Cache>* pCache;
72 auto it = m_Type3FaceMap.find(pFont); 53 auto it = m_Type3FaceMap.find(pFont);
73 if (it != m_Type3FaceMap.end()) 54 if (it == m_Type3FaceMap.end()) {
74 it->second->RemoveRef(); 55 CPDF_Type3Cache* pType3 = new CPDF_Type3Cache(pFont);
75 } 56 pCache = new CPDF_CountedObject<CPDF_Type3Cache>(pType3);
76 57 m_Type3FaceMap[pFont] = pCache;
77 class CPDF_RenderModule : public IPDF_RenderModule 58 } else {
78 { 59 pCache = it->second;
79 public: 60 }
80 CPDF_RenderModule() {} 61 return pCache->AddRef();
81 62 }
82 private: 63
83 ~CPDF_RenderModule() override {} 64 void CPDF_DocRenderData::ReleaseCachedType3(CPDF_Type3Font* pFont) {
84 65 auto it = m_Type3FaceMap.find(pFont);
85 CPDF_DocRenderData* CreateDocData(CPDF_Document* pDoc) override; 66 if (it != m_Type3FaceMap.end())
86 void DestroyDocData(CPDF_DocRenderData* p) override; 67 it->second->RemoveRef();
87 void ClearDocData(CPDF_DocRenderData* p) override; 68 }
88 69
89 CPDF_DocRenderData* GetRenderData() override 70 class CPDF_RenderModule : public IPDF_RenderModule {
90 { 71 public:
91 return &m_RenderData; 72 CPDF_RenderModule() {}
92 } 73
93 74 private:
94 CPDF_PageRenderCache* CreatePageCache(CPDF_Page* pPage) override 75 ~CPDF_RenderModule() override {}
95 { 76
96 return new CPDF_PageRenderCache(pPage); 77 CPDF_DocRenderData* CreateDocData(CPDF_Document* pDoc) override;
97 } 78 void DestroyDocData(CPDF_DocRenderData* p) override;
98 79 void ClearDocData(CPDF_DocRenderData* p) override;
99 void DestroyPageCache(CPDF_PageRenderCache* pCache) override; 80
100 81 CPDF_DocRenderData* GetRenderData() override { return &m_RenderData; }
101 CPDF_RenderConfig* GetConfig() override 82
102 { 83 CPDF_PageRenderCache* CreatePageCache(CPDF_Page* pPage) override {
103 return &m_RenderConfig; 84 return new CPDF_PageRenderCache(pPage);
104 } 85 }
105 86
106 CPDF_DocRenderData m_RenderData; 87 void DestroyPageCache(CPDF_PageRenderCache* pCache) override;
107 CPDF_RenderConfig m_RenderConfig; 88
89 CPDF_RenderConfig* GetConfig() override { return &m_RenderConfig; }
90
91 CPDF_DocRenderData m_RenderData;
92 CPDF_RenderConfig m_RenderConfig;
108 }; 93 };
109 94
110 CPDF_DocRenderData*» CPDF_RenderModule::CreateDocData(CPDF_Document* pDoc) 95 CPDF_DocRenderData* CPDF_RenderModule::CreateDocData(CPDF_Document* pDoc) {
111 { 96 return new CPDF_DocRenderData(pDoc);
112 return new CPDF_DocRenderData(pDoc); 97 }
113 } 98 void CPDF_RenderModule::DestroyDocData(CPDF_DocRenderData* pDocData) {
114 void CPDF_RenderModule::DestroyDocData(CPDF_DocRenderData* pDocData) 99 delete pDocData;
115 { 100 }
116 delete pDocData; 101 void CPDF_RenderModule::ClearDocData(CPDF_DocRenderData* p) {
117 } 102 if (p) {
118 void CPDF_RenderModule::ClearDocData(CPDF_DocRenderData* p) 103 p->Clear(FALSE);
119 { 104 }
120 if (p) { 105 }
121 p->Clear(FALSE); 106 void CPDF_RenderModule::DestroyPageCache(CPDF_PageRenderCache* pCache) {
122 } 107 delete pCache;
123 } 108 }
124 void CPDF_RenderModule::DestroyPageCache(CPDF_PageRenderCache* pCache) 109
125 { 110 void CPDF_ModuleMgr::InitRenderModule() {
126 delete pCache; 111 m_pRenderModule.reset(new CPDF_RenderModule);
127 }
128
129 void CPDF_ModuleMgr::InitRenderModule()
130 {
131 m_pRenderModule.reset(new CPDF_RenderModule);
132 } 112 }
133 113
134 CPDF_RenderOptions::CPDF_RenderOptions() 114 CPDF_RenderOptions::CPDF_RenderOptions()
135 : m_ColorMode(RENDER_COLOR_NORMAL) 115 : m_ColorMode(RENDER_COLOR_NORMAL),
136 , m_Flags(RENDER_CLEARTYPE) 116 m_Flags(RENDER_CLEARTYPE),
137 , m_Interpolation(0) 117 m_Interpolation(0),
138 , m_AddFlags(0) 118 m_AddFlags(0),
139 , m_pOCContext(NULL) 119 m_pOCContext(NULL),
140 , m_dwLimitCacheSize(1024 * 1024 * 100) 120 m_dwLimitCacheSize(1024 * 1024 * 100),
141 , m_HalftoneLimit(-1) 121 m_HalftoneLimit(-1) {}
142 { 122 FX_ARGB CPDF_RenderOptions::TranslateColor(FX_ARGB argb) const {
143 } 123 if (m_ColorMode == RENDER_COLOR_NORMAL) {
144 FX_ARGB CPDF_RenderOptions::TranslateColor(FX_ARGB argb) const 124 return argb;
145 { 125 }
146 if (m_ColorMode == RENDER_COLOR_NORMAL) { 126 if (m_ColorMode == RENDER_COLOR_ALPHA) {
147 return argb; 127 return argb;
148 } 128 }
149 if (m_ColorMode == RENDER_COLOR_ALPHA) { 129 int a, r, g, b;
150 return argb; 130 ArgbDecode(argb, a, r, g, b);
151 } 131 int gray = FXRGB2GRAY(r, g, b);
152 int a, r, g, b; 132 if (m_ColorMode == RENDER_COLOR_TWOCOLOR) {
153 ArgbDecode(argb, a, r, g, b); 133 int color = (r - gray) * (r - gray) + (g - gray) * (g - gray) +
154 int gray = FXRGB2GRAY(r, g, b); 134 (b - gray) * (b - gray);
155 if (m_ColorMode == RENDER_COLOR_TWOCOLOR) { 135 if (gray < 35 && color < 20) {
156 int color = (r - gray) * (r - gray) + (g - gray) * (g - gray) + (b - gra y) * (b - gray); 136 return ArgbEncode(a, m_ForeColor);
157 if (gray < 35 && color < 20) { 137 }
158 return ArgbEncode(a, m_ForeColor); 138 if (gray > 221 && color < 20) {
159 } 139 return ArgbEncode(a, m_BackColor);
160 if (gray > 221 && color < 20) { 140 }
161 return ArgbEncode(a, m_BackColor); 141 return argb;
162 } 142 }
163 return argb; 143 int fr = FXSYS_GetRValue(m_ForeColor);
164 } 144 int fg = FXSYS_GetGValue(m_ForeColor);
165 int fr = FXSYS_GetRValue(m_ForeColor); 145 int fb = FXSYS_GetBValue(m_ForeColor);
166 int fg = FXSYS_GetGValue(m_ForeColor); 146 int br = FXSYS_GetRValue(m_BackColor);
167 int fb = FXSYS_GetBValue(m_ForeColor); 147 int bg = FXSYS_GetGValue(m_BackColor);
168 int br = FXSYS_GetRValue(m_BackColor); 148 int bb = FXSYS_GetBValue(m_BackColor);
169 int bg = FXSYS_GetGValue(m_BackColor); 149 r = (br - fr) * gray / 255 + fr;
170 int bb = FXSYS_GetBValue(m_BackColor); 150 g = (bg - fg) * gray / 255 + fg;
171 r = (br - fr) * gray / 255 + fr; 151 b = (bb - fb) * gray / 255 + fb;
172 g = (bg - fg) * gray / 255 + fg; 152 return ArgbEncode(a, r, g, b);
173 b = (bb - fb) * gray / 255 + fb;
174 return ArgbEncode(a, r, g, b);
175 } 153 }
176 154
177 // static 155 // static
178 int CPDF_RenderStatus::s_CurrentRecursionDepth = 0; 156 int CPDF_RenderStatus::s_CurrentRecursionDepth = 0;
179 157
180 CPDF_RenderStatus::CPDF_RenderStatus() 158 CPDF_RenderStatus::CPDF_RenderStatus() {
181 { 159 m_pContext = NULL;
182 m_pContext = NULL; 160 m_bStopped = FALSE;
183 m_bStopped = FALSE; 161 m_pDevice = NULL;
184 m_pDevice = NULL; 162 m_pCurObj = NULL;
185 m_pCurObj = NULL; 163 m_pStopObj = NULL;
186 m_pStopObj = NULL; 164 m_HalftoneLimit = 0;
187 m_HalftoneLimit = 0; 165 m_pObjectRenderer = NULL;
166 m_bPrint = FALSE;
167 m_Transparency = 0;
168 m_DitherBits = 0;
169 m_bDropObjects = FALSE;
170 m_bStdCS = FALSE;
171 m_GroupFamily = 0;
172 m_bLoadMask = FALSE;
173 m_pType3Char = NULL;
174 m_T3FillColor = 0;
175 m_pFormResource = NULL;
176 m_pPageResource = NULL;
177 m_curBlend = FXDIB_BLEND_NORMAL;
178 }
179
180 CPDF_RenderStatus::~CPDF_RenderStatus() {
181 delete m_pObjectRenderer;
182 }
183
184 FX_BOOL CPDF_RenderStatus::Initialize(CPDF_RenderContext* pContext,
185 CFX_RenderDevice* pDevice,
186 const CFX_AffineMatrix* pDeviceMatrix,
187 const CPDF_PageObject* pStopObj,
188 const CPDF_RenderStatus* pParentState,
189 const CPDF_GraphicStates* pInitialStates,
190 const CPDF_RenderOptions* pOptions,
191 int transparency,
192 FX_BOOL bDropObjects,
193 CPDF_Dictionary* pFormResource,
194 FX_BOOL bStdCS,
195 CPDF_Type3Char* pType3Char,
196 FX_ARGB fill_color,
197 FX_DWORD GroupFamily,
198 FX_BOOL bLoadMask) {
199 m_pContext = pContext;
200 m_pDevice = pDevice;
201 m_DitherBits = pDevice->GetDeviceCaps(FXDC_DITHER_BITS);
202 m_bPrint = m_pDevice->GetDeviceClass() != FXDC_DISPLAY;
203 if (pDeviceMatrix) {
204 m_DeviceMatrix = *pDeviceMatrix;
205 }
206 m_pStopObj = pStopObj;
207 if (pOptions) {
208 m_Options = *pOptions;
209 }
210 m_bDropObjects = bDropObjects;
211 m_bStdCS = bStdCS;
212 m_T3FillColor = fill_color;
213 m_pType3Char = pType3Char;
214 m_GroupFamily = GroupFamily;
215 m_bLoadMask = bLoadMask;
216 m_pFormResource = pFormResource;
217 m_pPageResource = m_pContext->m_pPageResources;
218 if (pInitialStates && !m_pType3Char) {
219 m_InitialStates.CopyStates(*pInitialStates);
220 if (pParentState) {
221 CPDF_ColorStateData* pColorData =
222 (CPDF_ColorStateData*)(const CPDF_ColorStateData*)
223 m_InitialStates.m_ColorState;
224 CPDF_ColorStateData* pParentData =
225 (CPDF_ColorStateData*)(const CPDF_ColorStateData*)
226 pParentState->m_InitialStates.m_ColorState;
227 if (!pColorData || pColorData->m_FillColor.IsNull()) {
228 CPDF_ColorStateData* pData = m_InitialStates.m_ColorState.GetModify();
229 pData->m_FillRGB = pParentData->m_FillRGB;
230 pData->m_FillColor.Copy(&pParentData->m_FillColor);
231 }
232 if (!pColorData || pColorData->m_StrokeColor.IsNull()) {
233 CPDF_ColorStateData* pData = m_InitialStates.m_ColorState.GetModify();
234 pData->m_StrokeRGB = pParentData->m_FillRGB;
235 pData->m_StrokeColor.Copy(&pParentData->m_StrokeColor);
236 }
237 }
238 } else {
239 m_InitialStates.DefaultStates();
240 }
241 m_pObjectRenderer = NULL;
242 m_Transparency = transparency;
243 return TRUE;
244 }
245 void CPDF_RenderStatus::RenderObjectList(const CPDF_PageObjects* pObjs,
246 const CFX_AffineMatrix* pObj2Device) {
247 CFX_FloatRect clip_rect = m_pDevice->GetClipBox();
248 CFX_AffineMatrix device2object;
249 device2object.SetReverse(*pObj2Device);
250 device2object.TransformRect(clip_rect);
251 int index = 0;
252 FX_POSITION pos = pObjs->GetFirstObjectPosition();
253 while (pos) {
254 index++;
255 CPDF_PageObject* pCurObj = pObjs->GetNextObject(pos);
256 if (pCurObj == m_pStopObj) {
257 m_bStopped = TRUE;
258 return;
259 }
260 if (!pCurObj) {
261 continue;
262 }
263 if (pCurObj == NULL || pCurObj->m_Left > clip_rect.right ||
264 pCurObj->m_Right < clip_rect.left ||
265 pCurObj->m_Bottom > clip_rect.top ||
266 pCurObj->m_Top < clip_rect.bottom) {
267 continue;
268 }
269 RenderSingleObject(pCurObj, pObj2Device);
270 if (m_bStopped) {
271 return;
272 }
273 }
274 }
275 void CPDF_RenderStatus::RenderSingleObject(
276 const CPDF_PageObject* pObj,
277 const CFX_AffineMatrix* pObj2Device) {
278 CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth);
279 if (++s_CurrentRecursionDepth > kRenderMaxRecursionDepth) {
280 return;
281 }
282 m_pCurObj = pObj;
283 if (m_Options.m_pOCContext && pObj->m_ContentMark.NotNull()) {
284 if (!m_Options.m_pOCContext->CheckObjectVisible(pObj)) {
285 return;
286 }
287 }
288 ProcessClipPath(pObj->m_ClipPath, pObj2Device);
289 if (ProcessTransparency(pObj, pObj2Device)) {
290 return;
291 }
292 ProcessObjectNoClip(pObj, pObj2Device);
293 }
294 FX_BOOL CPDF_RenderStatus::ContinueSingleObject(
295 const CPDF_PageObject* pObj,
296 const CFX_AffineMatrix* pObj2Device,
297 IFX_Pause* pPause) {
298 if (m_pObjectRenderer) {
299 if (m_pObjectRenderer->Continue(pPause)) {
300 return TRUE;
301 }
302 if (!m_pObjectRenderer->m_Result) {
303 DrawObjWithBackground(pObj, pObj2Device);
304 }
305 delete m_pObjectRenderer;
188 m_pObjectRenderer = NULL; 306 m_pObjectRenderer = NULL;
189 m_bPrint = FALSE; 307 return FALSE;
190 m_Transparency = 0; 308 }
191 m_DitherBits = 0; 309 m_pCurObj = pObj;
192 m_bDropObjects = FALSE; 310 if (m_Options.m_pOCContext && pObj->m_ContentMark.NotNull())
193 m_bStdCS = FALSE; 311 if (!m_Options.m_pOCContext->CheckObjectVisible(pObj)) {
194 m_GroupFamily = 0; 312 return FALSE;
195 m_bLoadMask = FALSE; 313 }
196 m_pType3Char = NULL; 314 ProcessClipPath(pObj->m_ClipPath, pObj2Device);
197 m_T3FillColor = 0; 315 if (ProcessTransparency(pObj, pObj2Device)) {
198 m_pFormResource = NULL; 316 return FALSE;
199 m_pPageResource = NULL; 317 }
200 m_curBlend = FXDIB_BLEND_NORMAL; 318 if (pObj->m_Type == PDFPAGE_IMAGE) {
201 } 319 m_pObjectRenderer = IPDF_ObjectRenderer::Create(pObj->m_Type);
202 320 if (!m_pObjectRenderer->Start(this, pObj, pObj2Device, FALSE)) {
203 CPDF_RenderStatus::~CPDF_RenderStatus() 321 if (!m_pObjectRenderer->m_Result) {
204 { 322 DrawObjWithBackground(pObj, pObj2Device);
205 delete m_pObjectRenderer; 323 }
206 } 324 delete m_pObjectRenderer;
207 325 m_pObjectRenderer = NULL;
208 FX_BOOL CPDF_RenderStatus::Initialize(CPDF_RenderContext* pContext, CFX_RenderDe vice* pDevice, 326 return FALSE;
209 const CFX_AffineMatrix* pDeviceMatrix, con st CPDF_PageObject* pStopObj, 327 }
210 const CPDF_RenderStatus* pParentState, con st CPDF_GraphicStates* pInitialStates, 328 return ContinueSingleObject(pObj, pObj2Device, pPause);
211 const CPDF_RenderOptions* pOptions, int tr ansparency, FX_BOOL bDropObjects, 329 }
212 CPDF_Dictionary* pFormResource, FX_BOOL bS tdCS, CPDF_Type3Char* pType3Char, 330 ProcessObjectNoClip(pObj, pObj2Device);
213 FX_ARGB fill_color, FX_DWORD GroupFamily, 331 return FALSE;
214 FX_BOOL bLoadMask) 332 }
215 { 333 IPDF_ObjectRenderer* IPDF_ObjectRenderer::Create(int type) {
216 m_pContext = pContext; 334 if (type != PDFPAGE_IMAGE) {
217 m_pDevice = pDevice; 335 return NULL;
218 m_DitherBits = pDevice->GetDeviceCaps(FXDC_DITHER_BITS); 336 }
219 m_bPrint = m_pDevice->GetDeviceClass() != FXDC_DISPLAY; 337 return new CPDF_ImageRenderer;
220 if (pDeviceMatrix) { 338 }
221 m_DeviceMatrix = *pDeviceMatrix; 339 FX_BOOL CPDF_RenderStatus::GetObjectClippedRect(
222 } 340 const CPDF_PageObject* pObj,
223 m_pStopObj = pStopObj; 341 const CFX_AffineMatrix* pObj2Device,
224 if (pOptions) { 342 FX_BOOL bLogical,
225 m_Options = *pOptions; 343 FX_RECT& rect) const {
226 } 344 rect = pObj->GetBBox(pObj2Device);
227 m_bDropObjects = bDropObjects; 345 FX_RECT rtClip = m_pDevice->GetClipBox();
228 m_bStdCS = bStdCS; 346 if (!bLogical) {
229 m_T3FillColor = fill_color; 347 CFX_Matrix dCTM = m_pDevice->GetCTM();
230 m_pType3Char = pType3Char; 348 FX_FLOAT a = FXSYS_fabs(dCTM.a);
231 m_GroupFamily = GroupFamily; 349 FX_FLOAT d = FXSYS_fabs(dCTM.d);
232 m_bLoadMask = bLoadMask; 350 if (a != 1.0f || d != 1.0f) {
233 m_pFormResource = pFormResource; 351 rect.right = rect.left + (int32_t)FXSYS_ceil((FX_FLOAT)rect.Width() * a);
234 m_pPageResource = m_pContext->m_pPageResources; 352 rect.bottom = rect.top + (int32_t)FXSYS_ceil((FX_FLOAT)rect.Height() * d);
235 if (pInitialStates && !m_pType3Char) { 353 rtClip.right =
236 m_InitialStates.CopyStates(*pInitialStates); 354 rtClip.left + (int32_t)FXSYS_ceil((FX_FLOAT)rtClip.Width() * a);
237 if (pParentState) { 355 rtClip.bottom =
238 CPDF_ColorStateData* pColorData = (CPDF_ColorStateData*)(const CPDF_ ColorStateData*)m_InitialStates.m_ColorState; 356 rtClip.top + (int32_t)FXSYS_ceil((FX_FLOAT)rtClip.Height() * d);
239 CPDF_ColorStateData* pParentData = (CPDF_ColorStateData*)(const CPDF _ColorStateData*)pParentState->m_InitialStates.m_ColorState; 357 }
240 if (!pColorData || pColorData->m_FillColor.IsNull()) { 358 }
241 CPDF_ColorStateData* pData = m_InitialStates.m_ColorState.GetMod ify(); 359 rect.Intersect(rtClip);
242 pData->m_FillRGB = pParentData->m_FillRGB; 360 return rect.IsEmpty();
243 pData->m_FillColor.Copy(&pParentData->m_FillColor); 361 }
244 } 362 void CPDF_RenderStatus::DitherObjectArea(const CPDF_PageObject* pObj,
245 if (!pColorData || pColorData->m_StrokeColor.IsNull()) { 363 const CFX_AffineMatrix* pObj2Device) {
246 CPDF_ColorStateData* pData = m_InitialStates.m_ColorState.GetMod ify(); 364 CFX_DIBitmap* pBitmap = m_pDevice->GetBitmap();
247 pData->m_StrokeRGB = pParentData->m_FillRGB; 365 if (pBitmap == NULL) {
248 pData->m_StrokeColor.Copy(&pParentData->m_StrokeColor); 366 return;
249 } 367 }
368 FX_RECT rect;
369 if (GetObjectClippedRect(pObj, pObj2Device, FALSE, rect)) {
370 return;
371 }
372 if (m_DitherBits == 2) {
373 static FX_ARGB pal[4] = {0, 85, 170, 255};
374 pBitmap->DitherFS(pal, 4, &rect);
375 } else if (m_DitherBits == 3) {
376 static FX_ARGB pal[8] = {0, 36, 73, 109, 146, 182, 219, 255};
377 pBitmap->DitherFS(pal, 8, &rect);
378 } else if (m_DitherBits == 4) {
379 static FX_ARGB pal[16] = {0, 17, 34, 51, 68, 85, 102, 119,
380 136, 153, 170, 187, 204, 221, 238, 255};
381 pBitmap->DitherFS(pal, 16, &rect);
382 }
383 }
384 void CPDF_RenderStatus::ProcessObjectNoClip(
385 const CPDF_PageObject* pObj,
386 const CFX_AffineMatrix* pObj2Device) {
387 FX_BOOL bRet = FALSE;
388 switch (pObj->m_Type) {
389 case PDFPAGE_TEXT:
390 bRet = ProcessText((CPDF_TextObject*)pObj, pObj2Device, NULL);
391 break;
392 case PDFPAGE_PATH:
393 bRet = ProcessPath((CPDF_PathObject*)pObj, pObj2Device);
394 break;
395 case PDFPAGE_IMAGE:
396 bRet = ProcessImage((CPDF_ImageObject*)pObj, pObj2Device);
397 break;
398 case PDFPAGE_SHADING:
399 bRet = ProcessShading((CPDF_ShadingObject*)pObj, pObj2Device);
400 break;
401 case PDFPAGE_FORM:
402 bRet = ProcessForm((CPDF_FormObject*)pObj, pObj2Device);
403 break;
404 }
405 if (!bRet) {
406 DrawObjWithBackground(pObj, pObj2Device);
407 }
408 }
409 FX_BOOL CPDF_RenderStatus::DrawObjWithBlend(
410 const CPDF_PageObject* pObj,
411 const CFX_AffineMatrix* pObj2Device) {
412 FX_BOOL bRet = FALSE;
413 switch (pObj->m_Type) {
414 case PDFPAGE_PATH:
415 bRet = ProcessPath((CPDF_PathObject*)pObj, pObj2Device);
416 break;
417 case PDFPAGE_IMAGE:
418 bRet = ProcessImage((CPDF_ImageObject*)pObj, pObj2Device);
419 break;
420 case PDFPAGE_FORM:
421 bRet = ProcessForm((CPDF_FormObject*)pObj, pObj2Device);
422 break;
423 }
424 return bRet;
425 }
426 void CPDF_RenderStatus::GetScaledMatrix(CFX_Matrix& matrix) const {
427 CFX_Matrix dCTM = m_pDevice->GetCTM();
428 matrix.a *= FXSYS_fabs(dCTM.a);
429 matrix.d *= FXSYS_fabs(dCTM.d);
430 }
431 void CPDF_RenderStatus::DrawObjWithBackground(
432 const CPDF_PageObject* pObj,
433 const CFX_AffineMatrix* pObj2Device) {
434 FX_RECT rect;
435 if (GetObjectClippedRect(pObj, pObj2Device, FALSE, rect)) {
436 return;
437 }
438 int res = 300;
439 if (pObj->m_Type == PDFPAGE_IMAGE &&
440 m_pDevice->GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) {
441 res = 0;
442 }
443 CPDF_ScaledRenderBuffer buffer;
444 if (!buffer.Initialize(m_pContext, m_pDevice, &rect, pObj, &m_Options, res)) {
445 return;
446 }
447 CFX_AffineMatrix matrix = *pObj2Device;
448 matrix.Concat(*buffer.GetMatrix());
449 GetScaledMatrix(matrix);
450 CPDF_Dictionary* pFormResource = NULL;
451 if (pObj->m_Type == PDFPAGE_FORM) {
452 CPDF_FormObject* pFormObj = (CPDF_FormObject*)pObj;
453 if (pFormObj->m_pForm && pFormObj->m_pForm->m_pFormDict) {
454 pFormResource =
455 pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources"));
456 }
457 }
458 CPDF_RenderStatus status;
459 status.Initialize(m_pContext, buffer.GetDevice(), buffer.GetMatrix(), NULL,
460 NULL, NULL, &m_Options, m_Transparency, m_bDropObjects,
461 pFormResource);
462 status.RenderSingleObject(pObj, &matrix);
463 buffer.OutputToDevice();
464 }
465 FX_BOOL CPDF_RenderStatus::ProcessForm(CPDF_FormObject* pFormObj,
466 const CFX_AffineMatrix* pObj2Device) {
467 CPDF_Dictionary* pOC =
468 pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("OC"));
469 if (pOC && m_Options.m_pOCContext &&
470 !m_Options.m_pOCContext->CheckOCGVisible(pOC)) {
471 return TRUE;
472 }
473 CFX_AffineMatrix matrix = pFormObj->m_FormMatrix;
474 matrix.Concat(*pObj2Device);
475 CPDF_Dictionary* pResources = NULL;
476 if (pFormObj->m_pForm && pFormObj->m_pForm->m_pFormDict) {
477 pResources = pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources"));
478 }
479 CPDF_RenderStatus status;
480 status.Initialize(m_pContext, m_pDevice, NULL, m_pStopObj, this, pFormObj,
481 &m_Options, m_Transparency, m_bDropObjects, pResources,
482 FALSE);
483 status.m_curBlend = m_curBlend;
484 m_pDevice->SaveState();
485 status.RenderObjectList(pFormObj->m_pForm, &matrix);
486 m_bStopped = status.m_bStopped;
487 m_pDevice->RestoreState();
488 return TRUE;
489 }
490 FX_BOOL IsAvailableMatrix(const CFX_AffineMatrix& matrix) {
491 if (matrix.a == 0 || matrix.d == 0) {
492 return matrix.b != 0 && matrix.c != 0;
493 }
494 if (matrix.b == 0 || matrix.c == 0) {
495 return matrix.a != 0 && matrix.d != 0;
496 }
497 return TRUE;
498 }
499 FX_BOOL CPDF_RenderStatus::ProcessPath(CPDF_PathObject* pPathObj,
500 const CFX_AffineMatrix* pObj2Device) {
501 int FillType = pPathObj->m_FillType;
502 FX_BOOL bStroke = pPathObj->m_bStroke;
503 ProcessPathPattern(pPathObj, pObj2Device, FillType, bStroke);
504 if (FillType == 0 && !bStroke) {
505 return TRUE;
506 }
507 FX_DWORD fill_argb = 0;
508 if (FillType) {
509 fill_argb = GetFillArgb(pPathObj);
510 }
511 FX_DWORD stroke_argb = 0;
512 if (bStroke) {
513 stroke_argb = GetStrokeArgb(pPathObj);
514 }
515 CFX_AffineMatrix path_matrix = pPathObj->m_Matrix;
516 path_matrix.Concat(*pObj2Device);
517 if (!IsAvailableMatrix(path_matrix)) {
518 return TRUE;
519 }
520 if (FillType && (m_Options.m_Flags & RENDER_RECT_AA)) {
521 FillType |= FXFILL_RECT_AA;
522 }
523 if (m_Options.m_Flags & RENDER_FILL_FULLCOVER) {
524 FillType |= FXFILL_FULLCOVER;
525 }
526 if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) {
527 FillType |= FXFILL_NOPATHSMOOTH;
528 }
529 if (bStroke) {
530 FillType |= FX_FILL_STROKE;
531 }
532 const CPDF_GeneralStateData* pGeneralData =
533 ((CPDF_PageObject*)pPathObj)->m_GeneralState;
534 if (pGeneralData && pGeneralData->m_StrokeAdjust) {
535 FillType |= FX_STROKE_ADJUST;
536 }
537 if (m_pType3Char) {
538 FillType |= FX_FILL_TEXT_MODE;
539 }
540 CFX_GraphStateData graphState(*pPathObj->m_GraphState);
541 if (m_Options.m_Flags & RENDER_THINLINE) {
542 graphState.m_LineWidth = 0;
543 }
544 return m_pDevice->DrawPath(pPathObj->m_Path, &path_matrix, &graphState,
545 fill_argb, stroke_argb, FillType, 0, NULL,
546 m_curBlend);
547 }
548 CPDF_TransferFunc* CPDF_RenderStatus::GetTransferFunc(CPDF_Object* pObj) const {
549 ASSERT(pObj != NULL);
550 CPDF_DocRenderData* pDocCache = m_pContext->m_pDocument->GetRenderData();
551 if (!pDocCache) {
552 return NULL;
553 }
554 return pDocCache->GetTransferFunc(pObj);
555 }
556 FX_ARGB CPDF_RenderStatus::GetFillArgb(const CPDF_PageObject* pObj,
557 FX_BOOL bType3) const {
558 CPDF_ColorStateData* pColorData =
559 (CPDF_ColorStateData*)(const CPDF_ColorStateData*)pObj->m_ColorState;
560 if (m_pType3Char && !bType3 &&
561 (!m_pType3Char->m_bColored ||
562 (m_pType3Char->m_bColored &&
563 (!pColorData || pColorData->m_FillColor.IsNull())))) {
564 return m_T3FillColor;
565 }
566 if (!pColorData || pColorData->m_FillColor.IsNull()) {
567 pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)
568 m_InitialStates.m_ColorState;
569 }
570 FX_COLORREF rgb = pColorData->m_FillRGB;
571 if (rgb == (FX_DWORD)-1) {
572 return 0;
573 }
574 const CPDF_GeneralStateData* pGeneralData = pObj->m_GeneralState;
575 int alpha;
576 if (pGeneralData) {
577 alpha = (int32_t)(pGeneralData->m_FillAlpha * 255);
578 if (pGeneralData->m_pTR) {
579 if (!pGeneralData->m_pTransferFunc) {
580 ((CPDF_GeneralStateData*)pGeneralData)->m_pTransferFunc =
581 GetTransferFunc(pGeneralData->m_pTR);
582 }
583 if (pGeneralData->m_pTransferFunc) {
584 rgb = pGeneralData->m_pTransferFunc->TranslateColor(rgb);
585 }
586 }
587 } else {
588 alpha = 255;
589 }
590 return m_Options.TranslateColor(ArgbEncode(alpha, rgb));
591 }
592 FX_ARGB CPDF_RenderStatus::GetStrokeArgb(const CPDF_PageObject* pObj) const {
593 CPDF_ColorStateData* pColorData =
594 (CPDF_ColorStateData*)(const CPDF_ColorStateData*)pObj->m_ColorState;
595 if (m_pType3Char && (!m_pType3Char->m_bColored ||
596 (m_pType3Char->m_bColored &&
597 (!pColorData || pColorData->m_StrokeColor.IsNull())))) {
598 return m_T3FillColor;
599 }
600 if (!pColorData || pColorData->m_StrokeColor.IsNull()) {
601 pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)
602 m_InitialStates.m_ColorState;
603 }
604 FX_COLORREF rgb = pColorData->m_StrokeRGB;
605 if (rgb == (FX_DWORD)-1) {
606 return 0;
607 }
608 const CPDF_GeneralStateData* pGeneralData = pObj->m_GeneralState;
609 int alpha;
610 if (pGeneralData) {
611 alpha = (int32_t)(pGeneralData->m_StrokeAlpha * 255);
612 if (pGeneralData->m_pTR) {
613 if (!pGeneralData->m_pTransferFunc) {
614 ((CPDF_GeneralStateData*)pGeneralData)->m_pTransferFunc =
615 GetTransferFunc(pGeneralData->m_pTR);
616 }
617 if (pGeneralData->m_pTransferFunc) {
618 rgb = pGeneralData->m_pTransferFunc->TranslateColor(rgb);
619 }
620 }
621 } else {
622 alpha = 255;
623 }
624 return m_Options.TranslateColor(ArgbEncode(alpha, rgb));
625 }
626 void CPDF_RenderStatus::ProcessClipPath(CPDF_ClipPath ClipPath,
627 const CFX_AffineMatrix* pObj2Device) {
628 if (ClipPath.IsNull()) {
629 if (m_LastClipPath.IsNull()) {
630 return;
631 }
632 m_pDevice->RestoreState(TRUE);
633 m_LastClipPath.SetNull();
634 return;
635 }
636 if (m_LastClipPath == ClipPath) {
637 return;
638 }
639 m_LastClipPath = ClipPath;
640 m_pDevice->RestoreState(TRUE);
641 int nClipPath = ClipPath.GetPathCount();
642 int i;
643 for (i = 0; i < nClipPath; i++) {
644 const CFX_PathData* pPathData = ClipPath.GetPath(i);
645 if (pPathData == NULL) {
646 continue;
647 }
648 if (pPathData->GetPointCount() == 0) {
649 CFX_PathData EmptyPath;
650 EmptyPath.AppendRect(-1, -1, 0, 0);
651 int fill_mode = FXFILL_WINDING;
652 m_pDevice->SetClip_PathFill(&EmptyPath, NULL, fill_mode);
653 } else {
654 int ClipType = ClipPath.GetClipType(i);
655 m_pDevice->SetClip_PathFill(pPathData, pObj2Device, ClipType);
656 }
657 }
658 int textcount = ClipPath.GetTextCount();
659 if (textcount == 0) {
660 return;
661 }
662 if (m_pDevice->GetDeviceClass() == FXDC_DISPLAY &&
663 !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) {
664 return;
665 }
666 CFX_PathData* pTextClippingPath = NULL;
667 for (i = 0; i < textcount; i++) {
668 CPDF_TextObject* pText = ClipPath.GetText(i);
669 if (pText == NULL) {
670 if (pTextClippingPath) {
671 int fill_mode = FXFILL_WINDING;
672 if (m_Options.m_Flags & RENDER_NOTEXTSMOOTH) {
673 fill_mode |= FXFILL_NOPATHSMOOTH;
250 } 674 }
675 m_pDevice->SetClip_PathFill(pTextClippingPath, NULL, fill_mode);
676 delete pTextClippingPath;
677 pTextClippingPath = NULL;
678 }
251 } else { 679 } else {
252 m_InitialStates.DefaultStates(); 680 if (pTextClippingPath == NULL) {
253 } 681 pTextClippingPath = new CFX_PathData;
254 m_pObjectRenderer = NULL; 682 }
255 m_Transparency = transparency; 683 ProcessText(pText, pObj2Device, pTextClippingPath);
256 return TRUE; 684 }
257 } 685 }
258 void CPDF_RenderStatus::RenderObjectList(const CPDF_PageObjects* pObjs, const CF X_AffineMatrix* pObj2Device) 686 delete pTextClippingPath;
259 { 687 }
260 CFX_FloatRect clip_rect = m_pDevice->GetClipBox(); 688 void CPDF_RenderStatus::DrawClipPath(CPDF_ClipPath ClipPath,
261 CFX_AffineMatrix device2object; 689 const CFX_AffineMatrix* pObj2Device) {
262 device2object.SetReverse(*pObj2Device); 690 if (ClipPath.IsNull()) {
263 device2object.TransformRect(clip_rect); 691 return;
264 int index = 0; 692 }
265 FX_POSITION pos = pObjs->GetFirstObjectPosition(); 693 int fill_mode = 0;
266 while(pos) { 694 if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) {
267 index ++; 695 fill_mode |= FXFILL_NOPATHSMOOTH;
268 CPDF_PageObject* pCurObj = pObjs->GetNextObject(pos); 696 }
269 if (pCurObj == m_pStopObj) { 697 int nClipPath = ClipPath.GetPathCount();
270 m_bStopped = TRUE; 698 int i;
271 return; 699 for (i = 0; i < nClipPath; i++) {
272 } 700 const CFX_PathData* pPathData = ClipPath.GetPath(i);
273 if (!pCurObj) { 701 if (pPathData == NULL) {
274 continue; 702 continue;
275 } 703 }
276 if(pCurObj == NULL || pCurObj->m_Left > clip_rect.right || pCurObj->m_Ri ght < clip_rect.left || 704 CFX_GraphStateData stroke_state;
277 pCurObj->m_Bottom > clip_rect.top || pCurObj->m_Top < clip_rect. bottom) { 705 if (m_Options.m_Flags & RENDER_THINLINE) {
278 continue; 706 stroke_state.m_LineWidth = 0;
279 } 707 }
280 RenderSingleObject(pCurObj, pObj2Device); 708 m_pDevice->DrawPath(pPathData, pObj2Device, &stroke_state, 0, 0xffff0000,
281 if (m_bStopped) { 709 fill_mode);
282 return; 710 }
283 } 711 }
284 } 712 FX_BOOL CPDF_RenderStatus::SelectClipPath(CPDF_PathObject* pPathObj,
285 } 713 const CFX_AffineMatrix* pObj2Device,
286 void CPDF_RenderStatus::RenderSingleObject(const CPDF_PageObject* pObj, const CF X_AffineMatrix* pObj2Device) 714 FX_BOOL bStroke) {
287 { 715 CFX_AffineMatrix path_matrix = pPathObj->m_Matrix;
288 CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); 716 path_matrix.Concat(*pObj2Device);
289 if (++s_CurrentRecursionDepth > kRenderMaxRecursionDepth) { 717 if (bStroke) {
290 return;
291 }
292 m_pCurObj = pObj;
293 if (m_Options.m_pOCContext && pObj->m_ContentMark.NotNull()) {
294 if (!m_Options.m_pOCContext->CheckObjectVisible(pObj)) {
295 return;
296 }
297 }
298 ProcessClipPath(pObj->m_ClipPath, pObj2Device);
299 if (ProcessTransparency(pObj, pObj2Device)) {
300 return;
301 }
302 ProcessObjectNoClip(pObj, pObj2Device);
303 }
304 FX_BOOL CPDF_RenderStatus::ContinueSingleObject(const CPDF_PageObject* pObj, con st CFX_AffineMatrix* pObj2Device, IFX_Pause* pPause)
305 {
306 if (m_pObjectRenderer) {
307 if (m_pObjectRenderer->Continue(pPause)) {
308 return TRUE;
309 }
310 if (!m_pObjectRenderer->m_Result) {
311 DrawObjWithBackground(pObj, pObj2Device);
312 }
313 delete m_pObjectRenderer;
314 m_pObjectRenderer = NULL;
315 return FALSE;
316 }
317 m_pCurObj = pObj;
318 if (m_Options.m_pOCContext && pObj->m_ContentMark.NotNull())
319 if (!m_Options.m_pOCContext->CheckObjectVisible(pObj)) {
320 return FALSE;
321 }
322 ProcessClipPath(pObj->m_ClipPath, pObj2Device);
323 if (ProcessTransparency(pObj, pObj2Device)) {
324 return FALSE;
325 }
326 if (pObj->m_Type == PDFPAGE_IMAGE) {
327 m_pObjectRenderer = IPDF_ObjectRenderer::Create(pObj->m_Type);
328 if (!m_pObjectRenderer->Start(this, pObj, pObj2Device, FALSE)) {
329 if (!m_pObjectRenderer->m_Result) {
330 DrawObjWithBackground(pObj, pObj2Device);
331 }
332 delete m_pObjectRenderer;
333 m_pObjectRenderer = NULL;
334 return FALSE;
335 }
336 return ContinueSingleObject(pObj, pObj2Device, pPause);
337 }
338 ProcessObjectNoClip(pObj, pObj2Device);
339 return FALSE;
340 }
341 IPDF_ObjectRenderer* IPDF_ObjectRenderer::Create(int type)
342 {
343 if (type != PDFPAGE_IMAGE) {
344 return NULL;
345 }
346 return new CPDF_ImageRenderer;
347 }
348 FX_BOOL CPDF_RenderStatus::GetObjectClippedRect(const CPDF_PageObject* pObj, con st CFX_AffineMatrix* pObj2Device, FX_BOOL bLogical, FX_RECT &rect) const
349 {
350 rect = pObj->GetBBox(pObj2Device);
351 FX_RECT rtClip = m_pDevice->GetClipBox();
352 if (!bLogical) {
353 CFX_Matrix dCTM = m_pDevice->GetCTM();
354 FX_FLOAT a = FXSYS_fabs(dCTM.a);
355 FX_FLOAT d = FXSYS_fabs(dCTM.d);
356 if (a != 1.0f || d != 1.0f) {
357 rect.right = rect.left + (int32_t)FXSYS_ceil((FX_FLOAT)rect.Width() * a);
358 rect.bottom = rect.top + (int32_t)FXSYS_ceil((FX_FLOAT)rect.Height() * d);
359 rtClip.right = rtClip.left + (int32_t)FXSYS_ceil((FX_FLOAT)rtClip.Wi dth() * a);
360 rtClip.bottom = rtClip.top + (int32_t)FXSYS_ceil((FX_FLOAT)rtClip.He ight() * d);
361 }
362 }
363 rect.Intersect(rtClip);
364 return rect.IsEmpty();
365 }
366 void CPDF_RenderStatus::DitherObjectArea(const CPDF_PageObject* pObj, const CFX_ AffineMatrix* pObj2Device)
367 {
368 CFX_DIBitmap* pBitmap = m_pDevice->GetBitmap();
369 if (pBitmap == NULL) {
370 return;
371 }
372 FX_RECT rect;
373 if (GetObjectClippedRect(pObj, pObj2Device, FALSE, rect)) {
374 return;
375 }
376 if (m_DitherBits == 2) {
377 static FX_ARGB pal[4] = {0, 85, 170, 255};
378 pBitmap->DitherFS(pal, 4, &rect);
379 } else if (m_DitherBits == 3) {
380 static FX_ARGB pal[8] = {0, 36, 73, 109, 146, 182, 219, 255};
381 pBitmap->DitherFS(pal, 8, &rect);
382 } else if (m_DitherBits == 4) {
383 static FX_ARGB pal[16] = {0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170 , 187, 204, 221, 238, 255};
384 pBitmap->DitherFS(pal, 16, &rect);
385 }
386 }
387 void CPDF_RenderStatus::ProcessObjectNoClip(const CPDF_PageObject* pObj, const C FX_AffineMatrix* pObj2Device)
388 {
389 FX_BOOL bRet = FALSE;
390 switch (pObj->m_Type) {
391 case PDFPAGE_TEXT:
392 bRet = ProcessText((CPDF_TextObject*)pObj, pObj2Device, NULL);
393 break;
394 case PDFPAGE_PATH:
395 bRet = ProcessPath((CPDF_PathObject*)pObj, pObj2Device);
396 break;
397 case PDFPAGE_IMAGE:
398 bRet = ProcessImage((CPDF_ImageObject*)pObj, pObj2Device);
399 break;
400 case PDFPAGE_SHADING:
401 bRet = ProcessShading((CPDF_ShadingObject*)pObj, pObj2Device);
402 break;
403 case PDFPAGE_FORM:
404 bRet = ProcessForm((CPDF_FormObject*)pObj, pObj2Device);
405 break;
406 }
407 if (!bRet) {
408 DrawObjWithBackground(pObj, pObj2Device);
409 }
410 }
411 FX_BOOL CPDF_RenderStatus::DrawObjWithBlend(const CPDF_PageObject* pObj, const C FX_AffineMatrix* pObj2Device)
412 {
413 FX_BOOL bRet = FALSE;
414 switch (pObj->m_Type) {
415 case PDFPAGE_PATH:
416 bRet = ProcessPath((CPDF_PathObject*)pObj, pObj2Device);
417 break;
418 case PDFPAGE_IMAGE:
419 bRet = ProcessImage((CPDF_ImageObject *)pObj, pObj2Device);
420 break;
421 case PDFPAGE_FORM:
422 bRet = ProcessForm((CPDF_FormObject*)pObj, pObj2Device);
423 break;
424 }
425 return bRet;
426 }
427 void CPDF_RenderStatus::GetScaledMatrix(CFX_Matrix &matrix) const
428 {
429 CFX_Matrix dCTM = m_pDevice->GetCTM();
430 matrix.a *= FXSYS_fabs(dCTM.a);
431 matrix.d *= FXSYS_fabs(dCTM.d);
432 }
433 void CPDF_RenderStatus::DrawObjWithBackground(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device)
434 {
435 FX_RECT rect;
436 if (GetObjectClippedRect(pObj, pObj2Device, FALSE, rect)) {
437 return;
438 }
439 int res = 300;
440 if (pObj->m_Type == PDFPAGE_IMAGE && m_pDevice->GetDeviceCaps(FXDC_DEVICE_CL ASS) == FXDC_PRINTER) {
441 res = 0;
442 }
443 CPDF_ScaledRenderBuffer buffer;
444 if (!buffer.Initialize(m_pContext, m_pDevice, &rect, pObj, &m_Options, res)) {
445 return;
446 }
447 CFX_AffineMatrix matrix = *pObj2Device;
448 matrix.Concat(*buffer.GetMatrix());
449 GetScaledMatrix(matrix);
450 CPDF_Dictionary* pFormResource = NULL;
451 if (pObj->m_Type == PDFPAGE_FORM) {
452 CPDF_FormObject* pFormObj = (CPDF_FormObject*)pObj;
453 if (pFormObj->m_pForm && pFormObj->m_pForm->m_pFormDict) {
454 pFormResource = pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Re sources"));
455 }
456 }
457 CPDF_RenderStatus status;
458 status.Initialize(m_pContext, buffer.GetDevice(), buffer.GetMatrix(), NULL, NULL, NULL, &m_Options, m_Transparency, m_bDropObjects, pFormResource);
459 status.RenderSingleObject(pObj, &matrix);
460 buffer.OutputToDevice();
461 }
462 FX_BOOL CPDF_RenderStatus::ProcessForm(CPDF_FormObject* pFormObj, const CFX_Affi neMatrix* pObj2Device)
463 {
464 CPDF_Dictionary* pOC = pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("OC" ));
465 if (pOC && m_Options.m_pOCContext && !m_Options.m_pOCContext->CheckOCGVisibl e(pOC)) {
466 return TRUE;
467 }
468 CFX_AffineMatrix matrix = pFormObj->m_FormMatrix;
469 matrix.Concat(*pObj2Device);
470 CPDF_Dictionary* pResources = NULL;
471 if (pFormObj->m_pForm && pFormObj->m_pForm->m_pFormDict) {
472 pResources = pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources "));
473 }
474 CPDF_RenderStatus status;
475 status.Initialize(m_pContext, m_pDevice, NULL, m_pStopObj,
476 this, pFormObj, &m_Options, m_Transparency, m_bDropObjects , pResources, FALSE);
477 status.m_curBlend = m_curBlend;
478 m_pDevice->SaveState();
479 status.RenderObjectList(pFormObj->m_pForm, &matrix);
480 m_bStopped = status.m_bStopped;
481 m_pDevice->RestoreState();
482 return TRUE;
483 }
484 FX_BOOL IsAvailableMatrix(const CFX_AffineMatrix& matrix)
485 {
486 if (matrix.a == 0 || matrix.d == 0) {
487 return matrix.b != 0 && matrix.c != 0;
488 }
489 if (matrix.b == 0 || matrix.c == 0) {
490 return matrix.a != 0 && matrix.d != 0;
491 }
492 return TRUE;
493 }
494 FX_BOOL CPDF_RenderStatus::ProcessPath(CPDF_PathObject* pPathObj, const CFX_Affi neMatrix* pObj2Device)
495 {
496 int FillType = pPathObj->m_FillType;
497 FX_BOOL bStroke = pPathObj->m_bStroke;
498 ProcessPathPattern(pPathObj, pObj2Device, FillType, bStroke);
499 if (FillType == 0 && !bStroke) {
500 return TRUE;
501 }
502 FX_DWORD fill_argb = 0;
503 if (FillType) {
504 fill_argb = GetFillArgb(pPathObj);
505 }
506 FX_DWORD stroke_argb = 0;
507 if (bStroke) {
508 stroke_argb = GetStrokeArgb(pPathObj);
509 }
510 CFX_AffineMatrix path_matrix = pPathObj->m_Matrix;
511 path_matrix.Concat(*pObj2Device);
512 if (!IsAvailableMatrix(path_matrix)) {
513 return TRUE;
514 }
515 if (FillType && (m_Options.m_Flags & RENDER_RECT_AA)) {
516 FillType |= FXFILL_RECT_AA;
517 }
518 if (m_Options.m_Flags & RENDER_FILL_FULLCOVER) {
519 FillType |= FXFILL_FULLCOVER;
520 }
521 if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) {
522 FillType |= FXFILL_NOPATHSMOOTH;
523 }
524 if (bStroke) {
525 FillType |= FX_FILL_STROKE;
526 }
527 const CPDF_GeneralStateData* pGeneralData = ((CPDF_PageObject*)pPathObj)->m_ GeneralState;
528 if (pGeneralData && pGeneralData->m_StrokeAdjust) {
529 FillType |= FX_STROKE_ADJUST;
530 }
531 if (m_pType3Char) {
532 FillType |= FX_FILL_TEXT_MODE;
533 }
534 CFX_GraphStateData graphState(*pPathObj->m_GraphState); 718 CFX_GraphStateData graphState(*pPathObj->m_GraphState);
535 if (m_Options.m_Flags & RENDER_THINLINE) { 719 if (m_Options.m_Flags & RENDER_THINLINE) {
536 graphState.m_LineWidth = 0; 720 graphState.m_LineWidth = 0;
537 } 721 }
538 return m_pDevice->DrawPath(pPathObj->m_Path, &path_matrix, &graphState, fill _argb, stroke_argb, FillType, 0, NULL, m_curBlend); 722 return m_pDevice->SetClip_PathStroke(pPathObj->m_Path, &path_matrix,
539 } 723 &graphState);
540 CPDF_TransferFunc* CPDF_RenderStatus::GetTransferFunc(CPDF_Object* pObj) const 724 }
541 { 725 int fill_mode = pPathObj->m_FillType;
542 ASSERT(pObj != NULL); 726 if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) {
543 CPDF_DocRenderData* pDocCache = m_pContext->m_pDocument->GetRenderData(); 727 fill_mode |= FXFILL_NOPATHSMOOTH;
544 if (!pDocCache) { 728 }
545 return NULL; 729 return m_pDevice->SetClip_PathFill(pPathObj->m_Path, &path_matrix, fill_mode);
546 } 730 }
547 return pDocCache->GetTransferFunc(pObj); 731 FX_BOOL CPDF_RenderStatus::ProcessTransparency(
548 } 732 const CPDF_PageObject* pPageObj,
549 FX_ARGB CPDF_RenderStatus::GetFillArgb(const CPDF_PageObject* pObj, FX_BOOL bTyp e3) const 733 const CFX_AffineMatrix* pObj2Device) {
550 { 734 const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState;
551 CPDF_ColorStateData* pColorData = (CPDF_ColorStateData*)(const CPDF_ColorSta teData*)pObj->m_ColorState; 735 int blend_type =
552 if (m_pType3Char && !bType3 && (!m_pType3Char->m_bColored || (m_pType3Char-> m_bColored && (!pColorData || pColorData->m_FillColor.IsNull())))) { 736 pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NORMAL;
553 return m_T3FillColor; 737 if (blend_type == FXDIB_BLEND_UNSUPPORTED) {
554 } 738 return TRUE;
555 if (!pColorData || pColorData->m_FillColor.IsNull()) { 739 }
556 pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)m_Initial States.m_ColorState; 740 CPDF_Dictionary* pSMaskDict =
557 } 741 pGeneralState ? (CPDF_Dictionary*)pGeneralState->m_pSoftMask : NULL;
558 FX_COLORREF rgb = pColorData->m_FillRGB; 742 if (pSMaskDict) {
559 if (rgb == (FX_DWORD) - 1) { 743 if (pPageObj->m_Type == PDFPAGE_IMAGE &&
560 return 0; 744 ((CPDF_ImageObject*)pPageObj)
561 } 745 ->m_pImage->GetDict()
562 const CPDF_GeneralStateData* pGeneralData = pObj->m_GeneralState; 746 ->KeyExist(FX_BSTRC("SMask"))) {
563 int alpha; 747 pSMaskDict = NULL;
564 if (pGeneralData) { 748 }
565 alpha = (int32_t)(pGeneralData->m_FillAlpha * 255); 749 }
566 if (pGeneralData->m_pTR) { 750 CPDF_Dictionary* pFormResource = NULL;
567 if (!pGeneralData->m_pTransferFunc) { 751 FX_FLOAT group_alpha = 1.0f;
568 ((CPDF_GeneralStateData*)pGeneralData)->m_pTransferFunc = GetTra nsferFunc(pGeneralData->m_pTR); 752 int Transparency = m_Transparency;
569 } 753 FX_BOOL bGroupTransparent = FALSE;
570 if (pGeneralData->m_pTransferFunc) { 754 if (pPageObj->m_Type == PDFPAGE_FORM) {
571 rgb = pGeneralData->m_pTransferFunc->TranslateColor(rgb); 755 CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj;
572 } 756 const CPDF_GeneralStateData* pStateData =
573 } 757 pFormObj->m_GeneralState.GetObject();
758 if (pStateData) {
759 group_alpha = pStateData->m_FillAlpha;
760 }
761 Transparency = pFormObj->m_pForm->m_Transparency;
762 bGroupTransparent = Transparency & PDFTRANS_ISOLATED ? TRUE : FALSE;
763 if (pFormObj->m_pForm->m_pFormDict) {
764 pFormResource = pFormObj->m_pForm->m_pFormDict->GetDict("Resources");
765 }
766 }
767 FX_BOOL bTextClip = FALSE;
768 if (pPageObj->m_ClipPath.NotNull() && pPageObj->m_ClipPath.GetTextCount() &&
769 m_pDevice->GetDeviceClass() == FXDC_DISPLAY &&
770 !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) {
771 bTextClip = TRUE;
772 }
773 if ((m_Options.m_Flags & RENDER_OVERPRINT) &&
774 pPageObj->m_Type == PDFPAGE_IMAGE && pGeneralState &&
775 pGeneralState->m_FillOP && pGeneralState->m_StrokeOP) {
776 CPDF_Document* pDocument = NULL;
777 CPDF_Page* pPage = NULL;
778 if (m_pContext->m_pPageCache) {
779 pPage = m_pContext->m_pPageCache->GetPage();
780 pDocument = pPage->m_pDocument;
574 } else { 781 } else {
575 alpha = 255; 782 pDocument = ((CPDF_ImageObject*)pPageObj)->m_pImage->GetDocument();
576 } 783 }
577 return m_Options.TranslateColor(ArgbEncode(alpha, rgb)); 784 CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : NULL;
578 } 785 CPDF_Object* pCSObj = ((CPDF_ImageObject*)pPageObj)
579 FX_ARGB CPDF_RenderStatus::GetStrokeArgb(const CPDF_PageObject* pObj) const 786 ->m_pImage->GetStream()
580 { 787 ->GetDict()
581 CPDF_ColorStateData* pColorData = (CPDF_ColorStateData*)(const CPDF_ColorSta teData*)pObj->m_ColorState; 788 ->GetElementValue(FX_BSTRC("ColorSpace"));
582 if (m_pType3Char && (!m_pType3Char->m_bColored || (m_pType3Char->m_bColored && (!pColorData || pColorData->m_StrokeColor.IsNull())))) { 789 CPDF_ColorSpace* pColorSpace =
583 return m_T3FillColor; 790 pDocument->LoadColorSpace(pCSObj, pPageResources);
584 } 791 if (pColorSpace) {
585 if (!pColorData || pColorData->m_StrokeColor.IsNull()) { 792 int format = pColorSpace->GetFamily();
586 pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)m_Initial States.m_ColorState; 793 if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION ||
587 } 794 format == PDFCS_DEVICEN) {
588 FX_COLORREF rgb = pColorData->m_StrokeRGB; 795 blend_type = FXDIB_BLEND_DARKEN;
589 if (rgb == (FX_DWORD) - 1) { 796 }
590 return 0; 797 pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
591 } 798 }
592 const CPDF_GeneralStateData* pGeneralData = pObj->m_GeneralState; 799 }
593 int alpha; 800 if (pSMaskDict == NULL && group_alpha == 1.0f &&
594 if (pGeneralData) { 801 blend_type == FXDIB_BLEND_NORMAL && !bTextClip && !bGroupTransparent) {
595 alpha = (int32_t)(pGeneralData->m_StrokeAlpha * 255); 802 return FALSE;
596 if (pGeneralData->m_pTR) { 803 }
597 if (!pGeneralData->m_pTransferFunc) { 804 FX_BOOL isolated = Transparency & PDFTRANS_ISOLATED;
598 ((CPDF_GeneralStateData*)pGeneralData)->m_pTransferFunc = GetTra nsferFunc(pGeneralData->m_pTR); 805 if (m_bPrint) {
599 } 806 FX_BOOL bRet = FALSE;
600 if (pGeneralData->m_pTransferFunc) { 807 int rendCaps = m_pDevice->GetRenderCaps();
601 rgb = pGeneralData->m_pTransferFunc->TranslateColor(rgb); 808 if (!((Transparency & PDFTRANS_ISOLATED) || pSMaskDict || bTextClip) &&
602 } 809 (rendCaps & FXRC_BLEND_MODE)) {
603 } 810 int oldBlend = m_curBlend;
811 m_curBlend = blend_type;
812 bRet = DrawObjWithBlend(pPageObj, pObj2Device);
813 m_curBlend = oldBlend;
814 }
815 if (!bRet) {
816 DrawObjWithBackground(pPageObj, pObj2Device);
817 }
818 return TRUE;
819 }
820 FX_RECT rect = pPageObj->GetBBox(pObj2Device);
821 rect.Intersect(m_pDevice->GetClipBox());
822 if (rect.IsEmpty()) {
823 return TRUE;
824 }
825 CFX_Matrix deviceCTM = m_pDevice->GetCTM();
826 FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a);
827 FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d);
828 int width = FXSYS_round((FX_FLOAT)rect.Width() * scaleX);
829 int height = FXSYS_round((FX_FLOAT)rect.Height() * scaleY);
830 CFX_FxgeDevice bitmap_device;
831 CFX_DIBitmap* oriDevice = NULL;
832 if (!isolated && (m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) {
833 oriDevice = new CFX_DIBitmap;
834 if (!m_pDevice->CreateCompatibleBitmap(oriDevice, width, height)) {
835 return TRUE;
836 }
837 m_pDevice->GetDIBits(oriDevice, rect.left, rect.top);
838 }
839 if (!bitmap_device.Create(width, height, FXDIB_Argb, 0, oriDevice)) {
840 return TRUE;
841 }
842 CFX_DIBitmap* bitmap = bitmap_device.GetBitmap();
843 bitmap->Clear(0);
844 CFX_AffineMatrix new_matrix = *pObj2Device;
845 new_matrix.TranslateI(-rect.left, -rect.top);
846 new_matrix.Scale(scaleX, scaleY);
847 CFX_DIBitmap* pTextMask = NULL;
848 if (bTextClip) {
849 pTextMask = new CFX_DIBitmap;
850 if (!pTextMask->Create(width, height, FXDIB_8bppMask)) {
851 delete pTextMask;
852 return TRUE;
853 }
854 pTextMask->Clear(0);
855 CFX_FxgeDevice text_device;
856 text_device.Attach(pTextMask);
857 for (FX_DWORD i = 0; i < pPageObj->m_ClipPath.GetTextCount(); i++) {
858 CPDF_TextObject* textobj = pPageObj->m_ClipPath.GetText(i);
859 if (textobj == NULL) {
860 break;
861 }
862 CFX_AffineMatrix text_matrix;
863 textobj->GetTextMatrix(&text_matrix);
864 CPDF_TextRenderer::DrawTextPath(
865 &text_device, textobj->m_nChars, textobj->m_pCharCodes,
866 textobj->m_pCharPos, textobj->m_TextState.GetFont(),
867 textobj->m_TextState.GetFontSize(), &text_matrix, &new_matrix,
868 textobj->m_GraphState, (FX_ARGB)-1, 0, NULL);
869 }
870 }
871 CPDF_RenderStatus bitmap_render;
872 bitmap_render.Initialize(m_pContext, &bitmap_device, NULL, m_pStopObj, NULL,
873 NULL, &m_Options, 0, m_bDropObjects, pFormResource,
874 TRUE);
875 bitmap_render.ProcessObjectNoClip(pPageObj, &new_matrix);
876 m_bStopped = bitmap_render.m_bStopped;
877 if (pSMaskDict) {
878 CFX_AffineMatrix smask_matrix;
879 FXSYS_memcpy(&smask_matrix, pGeneralState->m_SMaskMatrix,
880 sizeof smask_matrix);
881 smask_matrix.Concat(*pObj2Device);
882 CFX_DIBSource* pSMaskSource = LoadSMask(pSMaskDict, &rect, &smask_matrix);
883 if (pSMaskSource) {
884 bitmap->MultiplyAlpha(pSMaskSource);
885 delete pSMaskSource;
886 }
887 }
888 if (pTextMask) {
889 bitmap->MultiplyAlpha(pTextMask);
890 delete pTextMask;
891 pTextMask = NULL;
892 }
893 if (Transparency & PDFTRANS_GROUP && group_alpha != 1.0f) {
894 bitmap->MultiplyAlpha((int32_t)(group_alpha * 255));
895 }
896 Transparency = m_Transparency;
897 if (pPageObj->m_Type == PDFPAGE_FORM) {
898 Transparency |= PDFTRANS_GROUP;
899 }
900 CompositeDIBitmap(bitmap, rect.left, rect.top, 0, 255, blend_type,
901 Transparency);
902 delete oriDevice;
903 return TRUE;
904 }
905 CFX_DIBitmap* CPDF_RenderStatus::GetBackdrop(const CPDF_PageObject* pObj,
906 const FX_RECT& rect,
907 int& left,
908 int& top,
909 FX_BOOL bBackAlphaRequired) {
910 FX_RECT bbox = rect;
911 bbox.Intersect(m_pDevice->GetClipBox());
912 left = bbox.left;
913 top = bbox.top;
914 CFX_Matrix deviceCTM = m_pDevice->GetCTM();
915 FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a);
916 FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d);
917 int width = FXSYS_round(bbox.Width() * scaleX);
918 int height = FXSYS_round(bbox.Height() * scaleY);
919 CFX_DIBitmap* pBackdrop = new CFX_DIBitmap;
920 if (bBackAlphaRequired && !m_bDropObjects) {
921 pBackdrop->Create(width, height, FXDIB_Argb);
922 } else {
923 m_pDevice->CreateCompatibleBitmap(pBackdrop, width, height);
924 }
925 if (pBackdrop->GetBuffer() == NULL) {
926 delete pBackdrop;
927 return NULL;
928 }
929 FX_BOOL bNeedDraw;
930 if (pBackdrop->HasAlpha()) {
931 bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT);
932 } else {
933 bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS);
934 }
935 if (!bNeedDraw) {
936 m_pDevice->GetDIBits(pBackdrop, left, top);
937 return pBackdrop;
938 }
939 CFX_AffineMatrix FinalMatrix = m_DeviceMatrix;
940 FinalMatrix.TranslateI(-left, -top);
941 FinalMatrix.Scale(scaleX, scaleY);
942 pBackdrop->Clear(pBackdrop->HasAlpha() ? 0 : 0xffffffff);
943 CFX_FxgeDevice device;
944 device.Attach(pBackdrop);
945 m_pContext->Render(&device, pObj, &m_Options, &FinalMatrix);
946 return pBackdrop;
947 }
948 void CPDF_RenderContext::GetBackground(CFX_DIBitmap* pBuffer,
949 const CPDF_PageObject* pObj,
950 const CPDF_RenderOptions* pOptions,
951 CFX_AffineMatrix* pFinalMatrix) {
952 CFX_FxgeDevice device;
953 device.Attach(pBuffer);
954
955 FX_RECT rect(0, 0, device.GetWidth(), device.GetHeight());
956 device.FillRect(&rect, 0xffffffff);
957 Render(&device, pObj, pOptions, pFinalMatrix);
958 }
959 CPDF_GraphicStates* CPDF_RenderStatus::CloneObjStates(
960 const CPDF_GraphicStates* pSrcStates,
961 FX_BOOL bStroke) {
962 if (!pSrcStates) {
963 return NULL;
964 }
965 CPDF_GraphicStates* pStates = new CPDF_GraphicStates;
966 pStates->CopyStates(*pSrcStates);
967 CPDF_Color* pObjColor = bStroke ? pSrcStates->m_ColorState.GetStrokeColor()
968 : pSrcStates->m_ColorState.GetFillColor();
969 if (!pObjColor->IsNull()) {
970 CPDF_ColorStateData* pColorData = pStates->m_ColorState.GetModify();
971 pColorData->m_FillRGB =
972 bStroke ? pSrcStates->m_ColorState.GetObject()->m_StrokeRGB
973 : pSrcStates->m_ColorState.GetObject()->m_FillRGB;
974 pColorData->m_StrokeRGB = pColorData->m_FillRGB;
975 }
976 return pStates;
977 }
978 CPDF_RenderContext::CPDF_RenderContext() {}
979 void CPDF_RenderContext::Create(CPDF_Document* pDoc,
980 CPDF_PageRenderCache* pPageCache,
981 CPDF_Dictionary* pPageResources,
982 FX_BOOL bFirstLayer) {
983 m_pDocument = pDoc;
984 m_pPageResources = pPageResources;
985 m_pPageCache = pPageCache;
986 m_bFirstLayer = bFirstLayer;
987 }
988 void CPDF_RenderContext::Create(CPDF_Page* pPage, FX_BOOL bFirstLayer) {
989 m_pDocument = pPage->m_pDocument;
990 m_pPageResources = pPage->m_pPageResources;
991 m_pPageCache = pPage->GetRenderCache();
992 m_bFirstLayer = bFirstLayer;
993 }
994 CPDF_RenderContext::~CPDF_RenderContext() {}
995 void CPDF_RenderContext::Clear() {
996 m_pDocument = NULL;
997 m_pPageResources = NULL;
998 m_pPageCache = NULL;
999 m_bFirstLayer = TRUE;
1000 m_ContentList.RemoveAll();
1001 }
1002 void CPDF_RenderContext::AppendObjectList(
1003 CPDF_PageObjects* pObjs,
1004 const CFX_AffineMatrix* pObject2Device) {
1005 _PDF_RenderItem* pItem = m_ContentList.AddSpace();
1006 pItem->m_pObjectList = pObjs;
1007 if (pObject2Device) {
1008 pItem->m_Matrix = *pObject2Device;
1009 } else {
1010 pItem->m_Matrix.SetIdentity();
1011 }
1012 }
1013 void CPDF_RenderContext::Render(CFX_RenderDevice* pDevice,
1014 const CPDF_RenderOptions* pOptions,
1015 const CFX_AffineMatrix* pLastMatrix) {
1016 Render(pDevice, NULL, pOptions, pLastMatrix);
1017 }
1018 void CPDF_RenderContext::Render(CFX_RenderDevice* pDevice,
1019 const CPDF_PageObject* pStopObj,
1020 const CPDF_RenderOptions* pOptions,
1021 const CFX_AffineMatrix* pLastMatrix) {
1022 int count = m_ContentList.GetSize();
1023 for (int j = 0; j < count; j++) {
1024 pDevice->SaveState();
1025 _PDF_RenderItem* pItem = m_ContentList.GetDataPtr(j);
1026 if (pLastMatrix) {
1027 CFX_AffineMatrix FinalMatrix = pItem->m_Matrix;
1028 FinalMatrix.Concat(*pLastMatrix);
1029 CPDF_RenderStatus status;
1030 status.Initialize(this, pDevice, pLastMatrix, pStopObj, NULL, NULL,
1031 pOptions, pItem->m_pObjectList->m_Transparency, FALSE,
1032 NULL);
1033 status.RenderObjectList(pItem->m_pObjectList, &FinalMatrix);
1034 if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) {
1035 m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheSize);
1036 }
1037 if (status.m_bStopped) {
1038 pDevice->RestoreState();
1039 break;
1040 }
604 } else { 1041 } else {
605 alpha = 255; 1042 CPDF_RenderStatus status;
606 } 1043 status.Initialize(this, pDevice, NULL, pStopObj, NULL, NULL, pOptions,
607 return m_Options.TranslateColor(ArgbEncode(alpha, rgb)); 1044 pItem->m_pObjectList->m_Transparency, FALSE, NULL);
608 } 1045 status.RenderObjectList(pItem->m_pObjectList, &pItem->m_Matrix);
609 void CPDF_RenderStatus::ProcessClipPath(CPDF_ClipPath ClipPath, const CFX_Affine Matrix* pObj2Device) 1046 if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) {
610 { 1047 m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheSize);
611 if (ClipPath.IsNull()) { 1048 }
612 if (m_LastClipPath.IsNull()) { 1049 if (status.m_bStopped) {
613 return;
614 }
615 m_pDevice->RestoreState(TRUE);
616 m_LastClipPath.SetNull();
617 return;
618 }
619 if (m_LastClipPath == ClipPath) {
620 return;
621 }
622 m_LastClipPath = ClipPath;
623 m_pDevice->RestoreState(TRUE);
624 int nClipPath = ClipPath.GetPathCount();
625 int i;
626 for (i = 0; i < nClipPath; i++) {
627 const CFX_PathData* pPathData = ClipPath.GetPath(i);
628 if (pPathData == NULL) {
629 continue;
630 }
631 if (pPathData->GetPointCount() == 0) {
632 CFX_PathData EmptyPath;
633 EmptyPath.AppendRect(-1, -1, 0, 0);
634 int fill_mode = FXFILL_WINDING;
635 m_pDevice->SetClip_PathFill(&EmptyPath, NULL, fill_mode);
636 } else {
637 int ClipType = ClipPath.GetClipType(i);
638 m_pDevice->SetClip_PathFill(pPathData, pObj2Device, ClipType);
639 }
640 }
641 int textcount = ClipPath.GetTextCount();
642 if (textcount == 0) {
643 return;
644 }
645 if (m_pDevice->GetDeviceClass() == FXDC_DISPLAY && !(m_pDevice->GetDeviceCap s(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) {
646 return;
647 }
648 CFX_PathData* pTextClippingPath = NULL;
649 for (i = 0; i < textcount; i ++) {
650 CPDF_TextObject* pText = ClipPath.GetText(i);
651 if (pText == NULL) {
652 if (pTextClippingPath) {
653 int fill_mode = FXFILL_WINDING;
654 if (m_Options.m_Flags & RENDER_NOTEXTSMOOTH) {
655 fill_mode |= FXFILL_NOPATHSMOOTH;
656 }
657 m_pDevice->SetClip_PathFill(pTextClippingPath, NULL, fill_mode);
658 delete pTextClippingPath;
659 pTextClippingPath = NULL;
660 }
661 } else {
662 if (pTextClippingPath == NULL) {
663 pTextClippingPath = new CFX_PathData;
664 }
665 ProcessText(pText, pObj2Device, pTextClippingPath);
666 }
667 }
668 delete pTextClippingPath;
669 }
670 void CPDF_RenderStatus::DrawClipPath(CPDF_ClipPath ClipPath, const CFX_AffineMat rix* pObj2Device)
671 {
672 if (ClipPath.IsNull()) {
673 return;
674 }
675 int fill_mode = 0;
676 if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) {
677 fill_mode |= FXFILL_NOPATHSMOOTH;
678 }
679 int nClipPath = ClipPath.GetPathCount();
680 int i;
681 for (i = 0; i < nClipPath; i++) {
682 const CFX_PathData* pPathData = ClipPath.GetPath(i);
683 if (pPathData == NULL) {
684 continue;
685 }
686 CFX_GraphStateData stroke_state;
687 if (m_Options.m_Flags & RENDER_THINLINE) {
688 stroke_state.m_LineWidth = 0;
689 }
690 m_pDevice->DrawPath(pPathData, pObj2Device, &stroke_state, 0, 0xffff0000 , fill_mode);
691 }
692 }
693 FX_BOOL CPDF_RenderStatus::SelectClipPath(CPDF_PathObject* pPathObj, const CFX_A ffineMatrix* pObj2Device, FX_BOOL bStroke)
694 {
695 CFX_AffineMatrix path_matrix = pPathObj->m_Matrix;
696 path_matrix.Concat(*pObj2Device);
697 if (bStroke) {
698 CFX_GraphStateData graphState(*pPathObj->m_GraphState);
699 if (m_Options.m_Flags & RENDER_THINLINE) {
700 graphState.m_LineWidth = 0;
701 }
702 return m_pDevice->SetClip_PathStroke(pPathObj->m_Path, &path_matrix, &gr aphState);
703 }
704 int fill_mode = pPathObj->m_FillType;
705 if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) {
706 fill_mode |= FXFILL_NOPATHSMOOTH;
707 }
708 return m_pDevice->SetClip_PathFill(pPathObj->m_Path, &path_matrix, fill_mode );
709 }
710 FX_BOOL CPDF_RenderStatus::ProcessTransparency(const CPDF_PageObject* pPageObj, const CFX_AffineMatrix* pObj2Device)
711 {
712 const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState;
713 int blend_type = pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NO RMAL;
714 if (blend_type == FXDIB_BLEND_UNSUPPORTED) {
715 return TRUE;
716 }
717 CPDF_Dictionary* pSMaskDict = pGeneralState ? (CPDF_Dictionary*)pGeneralStat e->m_pSoftMask : NULL;
718 if (pSMaskDict) {
719 if (pPageObj->m_Type == PDFPAGE_IMAGE &&
720 ((CPDF_ImageObject*)pPageObj)->m_pImage->GetDict()->KeyExist(FX_ BSTRC("SMask"))) {
721 pSMaskDict = NULL;
722 }
723 }
724 CPDF_Dictionary* pFormResource = NULL;
725 FX_FLOAT group_alpha = 1.0f;
726 int Transparency = m_Transparency;
727 FX_BOOL bGroupTransparent = FALSE;
728 if (pPageObj->m_Type == PDFPAGE_FORM) {
729 CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj;
730 const CPDF_GeneralStateData *pStateData = pFormObj->m_GeneralState.GetOb ject();
731 if (pStateData) {
732 group_alpha = pStateData->m_FillAlpha;
733 }
734 Transparency = pFormObj->m_pForm->m_Transparency;
735 bGroupTransparent = Transparency & PDFTRANS_ISOLATED ? TRUE : FALSE;
736 if (pFormObj->m_pForm->m_pFormDict) {
737 pFormResource = pFormObj->m_pForm->m_pFormDict->GetDict("Resources") ;
738 }
739 }
740 FX_BOOL bTextClip = FALSE;
741 if (pPageObj->m_ClipPath.NotNull() && pPageObj->m_ClipPath.GetTextCount() &&
742 m_pDevice->GetDeviceClass() == FXDC_DISPLAY && !(m_pDevice->GetDevic eCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) {
743 bTextClip = TRUE;
744 }
745 if ((m_Options.m_Flags & RENDER_OVERPRINT) && pPageObj->m_Type == PDFPAGE_IM AGE && pGeneralState && pGeneralState->m_FillOP && pGeneralState->m_StrokeOP) {
746 CPDF_Document* pDocument = NULL;
747 CPDF_Page* pPage = NULL;
748 if (m_pContext->m_pPageCache) {
749 pPage = m_pContext->m_pPageCache->GetPage();
750 pDocument = pPage->m_pDocument;
751 } else {
752 pDocument = ((CPDF_ImageObject*)pPageObj)->m_pImage->GetDocument();
753 }
754 CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : NULL ;
755 CPDF_Object* pCSObj = ((CPDF_ImageObject*)pPageObj)->m_pImage->GetStream ()->GetDict()->GetElementValue(FX_BSTRC("ColorSpace"));
756 CPDF_ColorSpace* pColorSpace = pDocument->LoadColorSpace(pCSObj, pPageRe sources);
757 if (pColorSpace) {
758 int format = pColorSpace->GetFamily();
759 if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION || form at == PDFCS_DEVICEN) {
760 blend_type = FXDIB_BLEND_DARKEN;
761 }
762 pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
763 }
764 }
765 if (pSMaskDict == NULL && group_alpha == 1.0f && blend_type == FXDIB_BLEND_N ORMAL && !bTextClip && !bGroupTransparent) {
766 return FALSE;
767 }
768 FX_BOOL isolated = Transparency & PDFTRANS_ISOLATED;
769 if (m_bPrint) {
770 FX_BOOL bRet = FALSE;
771 int rendCaps = m_pDevice->GetRenderCaps();
772 if (!((Transparency & PDFTRANS_ISOLATED) || pSMaskDict || bTextClip) && (rendCaps & FXRC_BLEND_MODE)) {
773 int oldBlend = m_curBlend;
774 m_curBlend = blend_type;
775 bRet = DrawObjWithBlend(pPageObj, pObj2Device);
776 m_curBlend = oldBlend;
777 }
778 if (!bRet) {
779 DrawObjWithBackground(pPageObj, pObj2Device);
780 }
781 return TRUE;
782 }
783 FX_RECT rect = pPageObj->GetBBox(pObj2Device);
784 rect.Intersect(m_pDevice->GetClipBox());
785 if (rect.IsEmpty()) {
786 return TRUE;
787 }
788 CFX_Matrix deviceCTM = m_pDevice->GetCTM();
789 FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a);
790 FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d);
791 int width = FXSYS_round((FX_FLOAT)rect.Width() * scaleX);
792 int height = FXSYS_round((FX_FLOAT)rect.Height() * scaleY);
793 CFX_FxgeDevice bitmap_device;
794 CFX_DIBitmap* oriDevice = NULL;
795 if (!isolated && (m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) {
796 oriDevice = new CFX_DIBitmap;
797 if (!m_pDevice->CreateCompatibleBitmap(oriDevice, width, height)) {
798 return TRUE;
799 }
800 m_pDevice->GetDIBits(oriDevice, rect.left, rect.top);
801 }
802 if (!bitmap_device.Create(width, height, FXDIB_Argb, 0, oriDevice)) {
803 return TRUE;
804 }
805 CFX_DIBitmap* bitmap = bitmap_device.GetBitmap();
806 bitmap->Clear(0);
807 CFX_AffineMatrix new_matrix = *pObj2Device;
808 new_matrix.TranslateI(-rect.left, -rect.top);
809 new_matrix.Scale(scaleX, scaleY);
810 CFX_DIBitmap* pTextMask = NULL;
811 if (bTextClip) {
812 pTextMask = new CFX_DIBitmap;
813 if (!pTextMask->Create(width, height, FXDIB_8bppMask)) {
814 delete pTextMask;
815 return TRUE;
816 }
817 pTextMask->Clear(0);
818 CFX_FxgeDevice text_device;
819 text_device.Attach(pTextMask);
820 for (FX_DWORD i = 0; i < pPageObj->m_ClipPath.GetTextCount(); i ++) {
821 CPDF_TextObject* textobj = pPageObj->m_ClipPath.GetText(i);
822 if (textobj == NULL) {
823 break;
824 }
825 CFX_AffineMatrix text_matrix;
826 textobj->GetTextMatrix(&text_matrix);
827 CPDF_TextRenderer::DrawTextPath(&text_device, textobj->m_nChars, tex tobj->m_pCharCodes, textobj->m_pCharPos,
828 textobj->m_TextState.GetFont(), text obj->m_TextState.GetFontSize(),
829 &text_matrix, &new_matrix, textobj-> m_GraphState, (FX_ARGB) - 1, 0, NULL);
830 }
831 }
832 CPDF_RenderStatus bitmap_render;
833 bitmap_render.Initialize(m_pContext, &bitmap_device, NULL,
834 m_pStopObj, NULL, NULL, &m_Options, 0, m_bDropObjec ts, pFormResource, TRUE);
835 bitmap_render.ProcessObjectNoClip(pPageObj, &new_matrix);
836 m_bStopped = bitmap_render.m_bStopped;
837 if (pSMaskDict) {
838 CFX_AffineMatrix smask_matrix;
839 FXSYS_memcpy(&smask_matrix, pGeneralState->m_SMaskMatrix, sizeof smask_m atrix);
840 smask_matrix.Concat(*pObj2Device);
841 CFX_DIBSource* pSMaskSource = LoadSMask(pSMaskDict, &rect, &smask_matrix );
842 if (pSMaskSource) {
843 bitmap->MultiplyAlpha(pSMaskSource);
844 delete pSMaskSource;
845 }
846 }
847 if (pTextMask) {
848 bitmap->MultiplyAlpha(pTextMask);
849 delete pTextMask;
850 pTextMask = NULL;
851 }
852 if (Transparency & PDFTRANS_GROUP && group_alpha != 1.0f) {
853 bitmap->MultiplyAlpha((int32_t)(group_alpha * 255));
854 }
855 Transparency = m_Transparency;
856 if (pPageObj->m_Type == PDFPAGE_FORM) {
857 Transparency |= PDFTRANS_GROUP;
858 }
859 CompositeDIBitmap(bitmap, rect.left, rect.top, 0, 255, blend_type, Transpare ncy);
860 delete oriDevice;
861 return TRUE;
862 }
863 CFX_DIBitmap* CPDF_RenderStatus::GetBackdrop(const CPDF_PageObject* pObj, const FX_RECT& rect, int& left, int& top,
864 FX_BOOL bBackAlphaRequired)
865 {
866 FX_RECT bbox = rect;
867 bbox.Intersect(m_pDevice->GetClipBox());
868 left = bbox.left;
869 top = bbox.top;
870 CFX_Matrix deviceCTM = m_pDevice->GetCTM();
871 FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a);
872 FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d);
873 int width = FXSYS_round(bbox.Width() * scaleX);
874 int height = FXSYS_round(bbox.Height() * scaleY);
875 CFX_DIBitmap* pBackdrop = new CFX_DIBitmap;
876 if (bBackAlphaRequired && !m_bDropObjects) {
877 pBackdrop->Create(width, height, FXDIB_Argb);
878 } else {
879 m_pDevice->CreateCompatibleBitmap(pBackdrop, width, height);
880 }
881 if (pBackdrop->GetBuffer() == NULL) {
882 delete pBackdrop;
883 return NULL;
884 }
885 FX_BOOL bNeedDraw;
886 if (pBackdrop->HasAlpha()) {
887 bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT);
888 } else {
889 bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS);
890 }
891 if (!bNeedDraw) {
892 m_pDevice->GetDIBits(pBackdrop, left, top);
893 return pBackdrop;
894 }
895 CFX_AffineMatrix FinalMatrix = m_DeviceMatrix;
896 FinalMatrix.TranslateI(-left, -top);
897 FinalMatrix.Scale(scaleX, scaleY);
898 pBackdrop->Clear(pBackdrop->HasAlpha() ? 0 : 0xffffffff);
899 CFX_FxgeDevice device;
900 device.Attach(pBackdrop);
901 m_pContext->Render(&device, pObj, &m_Options, &FinalMatrix);
902 return pBackdrop;
903 }
904 void CPDF_RenderContext::GetBackground(CFX_DIBitmap* pBuffer, const CPDF_PageObj ect* pObj,
905 const CPDF_RenderOptions* pOptions, CFX_A ffineMatrix* pFinalMatrix)
906 {
907 CFX_FxgeDevice device;
908 device.Attach(pBuffer);
909
910 FX_RECT rect(0, 0, device.GetWidth(), device.GetHeight());
911 device.FillRect(&rect, 0xffffffff);
912 Render(&device, pObj, pOptions, pFinalMatrix);
913 }
914 CPDF_GraphicStates* CPDF_RenderStatus::CloneObjStates(const CPDF_GraphicStates* pSrcStates, FX_BOOL bStroke)
915 {
916 if (!pSrcStates) {
917 return NULL;
918 }
919 CPDF_GraphicStates* pStates = new CPDF_GraphicStates;
920 pStates->CopyStates(*pSrcStates);
921 CPDF_Color* pObjColor = bStroke ? pSrcStates->m_ColorState.GetStrokeColor() :
922 pSrcStates->m_ColorState.GetFillColor();
923 if (!pObjColor->IsNull()) {
924 CPDF_ColorStateData* pColorData = pStates->m_ColorState.GetModify();
925 pColorData->m_FillRGB = bStroke ? pSrcStates->m_ColorState.GetObject()-> m_StrokeRGB :
926 pSrcStates->m_ColorState.GetObject()->m_FillRGB;
927 pColorData->m_StrokeRGB = pColorData->m_FillRGB;
928 }
929 return pStates;
930 }
931 CPDF_RenderContext::CPDF_RenderContext()
932 {
933 }
934 void CPDF_RenderContext::Create(CPDF_Document* pDoc, CPDF_PageRenderCache* pPage Cache,
935 CPDF_Dictionary* pPageResources, FX_BOOL bFirstL ayer)
936 {
937 m_pDocument = pDoc;
938 m_pPageResources = pPageResources;
939 m_pPageCache = pPageCache;
940 m_bFirstLayer = bFirstLayer;
941 }
942 void CPDF_RenderContext::Create(CPDF_Page* pPage, FX_BOOL bFirstLayer)
943 {
944 m_pDocument = pPage->m_pDocument;
945 m_pPageResources = pPage->m_pPageResources;
946 m_pPageCache = pPage->GetRenderCache();
947 m_bFirstLayer = bFirstLayer;
948 }
949 CPDF_RenderContext::~CPDF_RenderContext()
950 {
951 }
952 void CPDF_RenderContext::Clear()
953 {
954 m_pDocument = NULL;
955 m_pPageResources = NULL;
956 m_pPageCache = NULL;
957 m_bFirstLayer = TRUE;
958 m_ContentList.RemoveAll();
959 }
960 void CPDF_RenderContext::AppendObjectList(CPDF_PageObjects* pObjs, const CFX_Aff ineMatrix* pObject2Device)
961 {
962 _PDF_RenderItem* pItem = m_ContentList.AddSpace();
963 pItem->m_pObjectList = pObjs;
964 if (pObject2Device) {
965 pItem->m_Matrix = *pObject2Device;
966 } else {
967 pItem->m_Matrix.SetIdentity();
968 }
969 }
970 void CPDF_RenderContext::Render(CFX_RenderDevice* pDevice, const CPDF_RenderOpti ons* pOptions,
971 const CFX_AffineMatrix* pLastMatrix)
972 {
973 Render(pDevice, NULL, pOptions, pLastMatrix);
974 }
975 void CPDF_RenderContext::Render(CFX_RenderDevice* pDevice, const CPDF_PageObject * pStopObj,
976 const CPDF_RenderOptions* pOptions, const CFX_Af fineMatrix* pLastMatrix)
977 {
978 int count = m_ContentList.GetSize();
979 for (int j = 0; j < count; j ++) {
980 pDevice->SaveState();
981 _PDF_RenderItem* pItem = m_ContentList.GetDataPtr(j);
982 if (pLastMatrix) {
983 CFX_AffineMatrix FinalMatrix = pItem->m_Matrix;
984 FinalMatrix.Concat(*pLastMatrix);
985 CPDF_RenderStatus status;
986 status.Initialize(this, pDevice, pLastMatrix, pStopObj, NULL, NULL, pOptions,
987 pItem->m_pObjectList->m_Transparency, FALSE, NULL) ;
988 status.RenderObjectList(pItem->m_pObjectList, &FinalMatrix);
989 if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) {
990 m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheS ize);
991 }
992 if (status.m_bStopped) {
993 pDevice->RestoreState();
994 break;
995 }
996 } else {
997 CPDF_RenderStatus status;
998 status.Initialize(this, pDevice, NULL, pStopObj, NULL, NULL, pOption s,
999 pItem->m_pObjectList->m_Transparency, FALSE, NULL) ;
1000 status.RenderObjectList(pItem->m_pObjectList, &pItem->m_Matrix);
1001 if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) {
1002 m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheS ize);
1003 }
1004 if (status.m_bStopped) {
1005 pDevice->RestoreState();
1006 break;
1007 }
1008 }
1009 pDevice->RestoreState(); 1050 pDevice->RestoreState();
1010 } 1051 break;
1011 } 1052 }
1012 void CPDF_RenderContext::DrawObjectList(CFX_RenderDevice* pDevice, CPDF_PageObje cts* pObjs, 1053 }
1013 const CFX_AffineMatrix* pObject2Device, const CPDF_RenderOptions* pOptions) 1054 pDevice->RestoreState();
1014 { 1055 }
1015 AppendObjectList(pObjs, pObject2Device); 1056 }
1016 Render(pDevice, pOptions); 1057 void CPDF_RenderContext::DrawObjectList(CFX_RenderDevice* pDevice,
1058 CPDF_PageObjects* pObjs,
1059 const CFX_AffineMatrix* pObject2Device,
1060 const CPDF_RenderOptions* pOptions) {
1061 AppendObjectList(pObjs, pObject2Device);
1062 Render(pDevice, pOptions);
1017 } 1063 }
1018 1064
1019 CPDF_ProgressiveRenderer::CPDF_ProgressiveRenderer( 1065 CPDF_ProgressiveRenderer::CPDF_ProgressiveRenderer(
1020 CPDF_RenderContext* pContext, 1066 CPDF_RenderContext* pContext,
1021 CFX_RenderDevice* pDevice, 1067 CFX_RenderDevice* pDevice,
1022 const CPDF_RenderOptions* pOptions) : 1068 const CPDF_RenderOptions* pOptions)
1023 m_Status(Ready), 1069 : m_Status(Ready),
1024 m_pContext(pContext), 1070 m_pContext(pContext),
1025 m_pDevice(pDevice), 1071 m_pDevice(pDevice),
1026 m_pOptions(pOptions), 1072 m_pOptions(pOptions),
1027 m_LayerIndex(0), 1073 m_LayerIndex(0),
1028 m_ObjectIndex(0), 1074 m_ObjectIndex(0),
1029 m_ObjectPos(nullptr), 1075 m_ObjectPos(nullptr),
1030 m_PrevLastPos(nullptr) 1076 m_PrevLastPos(nullptr) {}
1031 { 1077
1032 } 1078 CPDF_ProgressiveRenderer::~CPDF_ProgressiveRenderer() {
1033 1079 if (m_pRenderStatus)
1034 CPDF_ProgressiveRenderer::~CPDF_ProgressiveRenderer() 1080 m_pDevice->RestoreState();
1035 { 1081 }
1036 if (m_pRenderStatus) 1082
1037 m_pDevice->RestoreState(); 1083 void CPDF_ProgressiveRenderer::Start(IFX_Pause* pPause) {
1038 } 1084 if (!m_pContext || !m_pDevice || m_Status != Ready) {
1039 1085 m_Status = Failed;
1040 void CPDF_ProgressiveRenderer::Start(IFX_Pause* pPause) 1086 return;
1041 { 1087 }
1042 if (!m_pContext || !m_pDevice || m_Status != Ready) { 1088 m_Status = ToBeContinued;
1043 m_Status = Failed; 1089 Continue(pPause);
1044 return;
1045 }
1046 m_Status = ToBeContinued;
1047 Continue(pPause);
1048 } 1090 }
1049 1091
1050 #define RENDER_STEP_LIMIT 100 1092 #define RENDER_STEP_LIMIT 100
1051 void CPDF_ProgressiveRenderer::Continue(IFX_Pause* pPause) 1093 void CPDF_ProgressiveRenderer::Continue(IFX_Pause* pPause) {
1052 { 1094 if (m_Status != ToBeContinued) {
1053 if (m_Status != ToBeContinued) { 1095 return;
1054 return; 1096 }
1055 } 1097 FX_DWORD nLayers = m_pContext->m_ContentList.GetSize();
1056 FX_DWORD nLayers = m_pContext->m_ContentList.GetSize(); 1098 for (; m_LayerIndex < nLayers; m_LayerIndex++) {
1057 for (; m_LayerIndex < nLayers; m_LayerIndex ++) { 1099 _PDF_RenderItem* pItem = m_pContext->m_ContentList.GetDataPtr(m_LayerIndex);
1058 _PDF_RenderItem* pItem = m_pContext->m_ContentList.GetDataPtr(m_LayerInd ex); 1100 FX_POSITION LastPos = pItem->m_pObjectList->GetLastObjectPosition();
1059 FX_POSITION LastPos = pItem->m_pObjectList->GetLastObjectPosition(); 1101 if (m_ObjectPos == NULL) {
1060 if (m_ObjectPos == NULL) { 1102 if (LastPos == m_PrevLastPos) {
1061 if (LastPos == m_PrevLastPos) { 1103 if (!pItem->m_pObjectList->IsParsed()) {
1062 if (!pItem->m_pObjectList->IsParsed()) { 1104 pItem->m_pObjectList->ContinueParse(pPause);
1063 pItem->m_pObjectList->ContinueParse(pPause); 1105 if (!pItem->m_pObjectList->IsParsed()) {
1064 if (!pItem->m_pObjectList->IsParsed()) { 1106 return;
1065 return; 1107 }
1066 } 1108 LastPos = pItem->m_pObjectList->GetLastObjectPosition();
1067 LastPos = pItem->m_pObjectList->GetLastObjectPosition();
1068 }
1069 }
1070 if (LastPos == m_PrevLastPos) {
1071 if (m_pRenderStatus) {
1072 m_pRenderStatus.reset();
1073 m_pDevice->RestoreState();
1074 m_ObjectPos = NULL;
1075 m_PrevLastPos = NULL;
1076 }
1077 continue;
1078 }
1079 if (m_PrevLastPos) {
1080 m_ObjectPos = m_PrevLastPos;
1081 pItem->m_pObjectList->GetNextObject(m_ObjectPos);
1082 } else {
1083 m_ObjectPos = pItem->m_pObjectList->GetFirstObjectPosition();
1084 }
1085 m_PrevLastPos = LastPos;
1086 } 1109 }
1087 if (!m_pRenderStatus) { 1110 }
1088 m_ObjectPos = pItem->m_pObjectList->GetFirstObjectPosition(); 1111 if (LastPos == m_PrevLastPos) {
1089 m_ObjectIndex = 0; 1112 if (m_pRenderStatus) {
1090 m_pRenderStatus.reset(new CPDF_RenderStatus()); 1113 m_pRenderStatus.reset();
1091 m_pRenderStatus->Initialize( 1114 m_pDevice->RestoreState();
1092 m_pContext, m_pDevice, NULL, NULL, NULL, NULL, m_pOptions, 1115 m_ObjectPos = NULL;
1093 pItem->m_pObjectList->m_Transparency, FALSE, NULL); 1116 m_PrevLastPos = NULL;
1094 m_pDevice->SaveState();
1095 m_ClipRect = m_pDevice->GetClipBox();
1096 CFX_AffineMatrix device2object;
1097 device2object.SetReverse(pItem->m_Matrix);
1098 device2object.TransformRect(m_ClipRect);
1099 } 1117 }
1100 int objs_to_go = CPDF_ModuleMgr::Get()->GetRenderModule()->GetConfig()-> m_RenderStepLimit; 1118 continue;
1101 while (m_ObjectPos) { 1119 }
1102 CPDF_PageObject* pCurObj = pItem->m_pObjectList->GetObjectAt(m_Objec tPos); 1120 if (m_PrevLastPos) {
1103 if (pCurObj && pCurObj->m_Left <= m_ClipRect.right && pCurObj->m_Rig ht >= m_ClipRect.left && 1121 m_ObjectPos = m_PrevLastPos;
1104 pCurObj->m_Bottom <= m_ClipRect.top && pCurObj->m_Top >= m_C lipRect.bottom) { 1122 pItem->m_pObjectList->GetNextObject(m_ObjectPos);
1105 if (m_pRenderStatus->ContinueSingleObject(pCurObj, &pItem->m_Mat rix, pPause)) { 1123 } else {
1106 return; 1124 m_ObjectPos = pItem->m_pObjectList->GetFirstObjectPosition();
1107 } 1125 }
1108 if (pCurObj->m_Type == PDFPAGE_IMAGE && m_pRenderStatus->m_Optio ns.m_Flags & RENDER_LIMITEDIMAGECACHE) { 1126 m_PrevLastPos = LastPos;
1109 m_pContext->GetPageCache()->CacheOptimization(m_pRenderStatu s->m_Options.m_dwLimitCacheSize); 1127 }
1110 } 1128 if (!m_pRenderStatus) {
1111 if (pCurObj->m_Type == PDFPAGE_FORM || pCurObj->m_Type == PDFPAG E_SHADING) { 1129 m_ObjectPos = pItem->m_pObjectList->GetFirstObjectPosition();
1112 objs_to_go = 0; 1130 m_ObjectIndex = 0;
1113 } else { 1131 m_pRenderStatus.reset(new CPDF_RenderStatus());
1114 objs_to_go --; 1132 m_pRenderStatus->Initialize(
1115 } 1133 m_pContext, m_pDevice, NULL, NULL, NULL, NULL, m_pOptions,
1116 } 1134 pItem->m_pObjectList->m_Transparency, FALSE, NULL);
1117 m_ObjectIndex ++; 1135 m_pDevice->SaveState();
1118 pItem->m_pObjectList->GetNextObject(m_ObjectPos); 1136 m_ClipRect = m_pDevice->GetClipBox();
1119 if (objs_to_go == 0) { 1137 CFX_AffineMatrix device2object;
1120 if (pPause && pPause->NeedToPauseNow()) { 1138 device2object.SetReverse(pItem->m_Matrix);
1121 return; 1139 device2object.TransformRect(m_ClipRect);
1122 } 1140 }
1123 objs_to_go = CPDF_ModuleMgr::Get()->GetRenderModule()->GetConfig ()->m_RenderStepLimit; 1141 int objs_to_go = CPDF_ModuleMgr::Get()
1124 } 1142 ->GetRenderModule()
1143 ->GetConfig()
1144 ->m_RenderStepLimit;
1145 while (m_ObjectPos) {
1146 CPDF_PageObject* pCurObj = pItem->m_pObjectList->GetObjectAt(m_ObjectPos);
1147 if (pCurObj && pCurObj->m_Left <= m_ClipRect.right &&
1148 pCurObj->m_Right >= m_ClipRect.left &&
1149 pCurObj->m_Bottom <= m_ClipRect.top &&
1150 pCurObj->m_Top >= m_ClipRect.bottom) {
1151 if (m_pRenderStatus->ContinueSingleObject(pCurObj, &pItem->m_Matrix,
1152 pPause)) {
1153 return;
1125 } 1154 }
1126 if (!pItem->m_pObjectList->IsParsed()) { 1155 if (pCurObj->m_Type == PDFPAGE_IMAGE &&
1127 return; 1156 m_pRenderStatus->m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) {
1157 m_pContext->GetPageCache()->CacheOptimization(
1158 m_pRenderStatus->m_Options.m_dwLimitCacheSize);
1128 } 1159 }
1129 m_pRenderStatus.reset(); 1160 if (pCurObj->m_Type == PDFPAGE_FORM ||
1130 m_pDevice->RestoreState(); 1161 pCurObj->m_Type == PDFPAGE_SHADING) {
1131 m_ObjectPos = NULL; 1162 objs_to_go = 0;
1132 m_PrevLastPos = NULL; 1163 } else {
1164 objs_to_go--;
1165 }
1166 }
1167 m_ObjectIndex++;
1168 pItem->m_pObjectList->GetNextObject(m_ObjectPos);
1169 if (objs_to_go == 0) {
1133 if (pPause && pPause->NeedToPauseNow()) { 1170 if (pPause && pPause->NeedToPauseNow()) {
1134 m_LayerIndex++; 1171 return;
1135 return;
1136 } 1172 }
1137 } 1173 objs_to_go = CPDF_ModuleMgr::Get()
1138 m_Status = Done; 1174 ->GetRenderModule()
1139 } 1175 ->GetConfig()
1140 int CPDF_ProgressiveRenderer::EstimateProgress() 1176 ->m_RenderStepLimit;
1141 { 1177 }
1142 if (!m_pContext) { 1178 }
1143 return 0; 1179 if (!pItem->m_pObjectList->IsParsed()) {
1144 } 1180 return;
1145 FX_DWORD nLayers = m_pContext->m_ContentList.GetSize(); 1181 }
1146 int nTotal = 0, nRendered = 0; 1182 m_pRenderStatus.reset();
1147 for (FX_DWORD layer = 0; layer < nLayers; layer ++) { 1183 m_pDevice->RestoreState();
1148 _PDF_RenderItem* pItem = m_pContext->m_ContentList.GetDataPtr(layer); 1184 m_ObjectPos = NULL;
1149 int nObjs = pItem->m_pObjectList->CountObjects(); 1185 m_PrevLastPos = NULL;
1150 if (layer == m_LayerIndex) { 1186 if (pPause && pPause->NeedToPauseNow()) {
1151 nRendered += m_ObjectIndex; 1187 m_LayerIndex++;
1152 } else if (layer < m_LayerIndex) { 1188 return;
1153 nRendered += nObjs; 1189 }
1190 }
1191 m_Status = Done;
1192 }
1193 int CPDF_ProgressiveRenderer::EstimateProgress() {
1194 if (!m_pContext) {
1195 return 0;
1196 }
1197 FX_DWORD nLayers = m_pContext->m_ContentList.GetSize();
1198 int nTotal = 0, nRendered = 0;
1199 for (FX_DWORD layer = 0; layer < nLayers; layer++) {
1200 _PDF_RenderItem* pItem = m_pContext->m_ContentList.GetDataPtr(layer);
1201 int nObjs = pItem->m_pObjectList->CountObjects();
1202 if (layer == m_LayerIndex) {
1203 nRendered += m_ObjectIndex;
1204 } else if (layer < m_LayerIndex) {
1205 nRendered += nObjs;
1206 }
1207 nTotal += nObjs;
1208 }
1209 if (nTotal == 0) {
1210 return 0;
1211 }
1212 return 100 * nRendered / nTotal;
1213 }
1214 CPDF_TransferFunc* CPDF_DocRenderData::GetTransferFunc(CPDF_Object* pObj) {
1215 if (!pObj)
1216 return nullptr;
1217
1218 auto it = m_TransferFuncMap.find(pObj);
1219 if (it != m_TransferFuncMap.end()) {
1220 CPDF_CountedObject<CPDF_TransferFunc>* pTransferCounter = it->second;
1221 return pTransferCounter->AddRef();
1222 }
1223
1224 CPDF_Function* pFuncs[3] = {nullptr, nullptr, nullptr};
1225 FX_BOOL bUniTransfer = TRUE;
1226 FX_BOOL bIdentity = TRUE;
1227 if (pObj->GetType() == PDFOBJ_ARRAY) {
1228 bUniTransfer = FALSE;
1229 CPDF_Array* pArray = (CPDF_Array*)pObj;
1230 if (pArray->GetCount() < 3)
1231 return nullptr;
1232
1233 for (FX_DWORD i = 0; i < 3; ++i) {
1234 pFuncs[2 - i] = CPDF_Function::Load(pArray->GetElementValue(i));
1235 if (!pFuncs[2 - i]) {
1236 return nullptr;
1237 }
1238 }
1239 } else {
1240 pFuncs[0] = CPDF_Function::Load(pObj);
1241 if (!pFuncs[0]) {
1242 return nullptr;
1243 }
1244 }
1245 CPDF_TransferFunc* pTransfer = new CPDF_TransferFunc;
1246 pTransfer->m_pPDFDoc = m_pPDFDoc;
1247 CPDF_CountedObject<CPDF_TransferFunc>* pTransferCounter =
1248 new CPDF_CountedObject<CPDF_TransferFunc>(pTransfer);
1249 m_TransferFuncMap[pObj] = pTransferCounter;
1250 static const int kMaxOutputs = 16;
1251 FX_FLOAT output[kMaxOutputs];
1252 FXSYS_memset(output, 0, sizeof(output));
1253 FX_FLOAT input;
1254 int noutput;
1255 for (int v = 0; v < 256; ++v) {
1256 input = (FX_FLOAT)v / 255.0f;
1257 if (bUniTransfer) {
1258 if (pFuncs[0] && pFuncs[0]->CountOutputs() <= kMaxOutputs)
1259 pFuncs[0]->Call(&input, 1, output, noutput);
1260 int o = FXSYS_round(output[0] * 255);
1261 if (o != v)
1262 bIdentity = FALSE;
1263 for (int i = 0; i < 3; ++i) {
1264 pTransfer->m_Samples[i * 256 + v] = o;
1265 }
1266 } else {
1267 for (int i = 0; i < 3; ++i) {
1268 if (pFuncs[i] && pFuncs[i]->CountOutputs() <= kMaxOutputs) {
1269 pFuncs[i]->Call(&input, 1, output, noutput);
1270 int o = FXSYS_round(output[0] * 255);
1271 if (o != v)
1272 bIdentity = FALSE;
1273 pTransfer->m_Samples[i * 256 + v] = o;
1274 } else {
1275 pTransfer->m_Samples[i * 256 + v] = v;
1154 } 1276 }
1155 nTotal += nObjs; 1277 }
1156 } 1278 }
1157 if (nTotal == 0) { 1279 }
1158 return 0; 1280 for (int i = 0; i < 3; ++i)
1159 } 1281 delete pFuncs[i];
1160 return 100 * nRendered / nTotal; 1282
1161 } 1283 pTransfer->m_bIdentity = bIdentity;
1162 CPDF_TransferFunc* CPDF_DocRenderData::GetTransferFunc(CPDF_Object* pObj) 1284 return pTransferCounter->AddRef();
1163 { 1285 }
1164 if (!pObj) 1286
1165 return nullptr; 1287 void CPDF_DocRenderData::ReleaseTransferFunc(CPDF_Object* pObj) {
1166 1288 auto it = m_TransferFuncMap.find(pObj);
1167 auto it = m_TransferFuncMap.find(pObj); 1289 if (it != m_TransferFuncMap.end())
1168 if (it != m_TransferFuncMap.end()) { 1290 it->second->RemoveRef();
1169 CPDF_CountedObject<CPDF_TransferFunc>* pTransferCounter = it->second; 1291 }
1170 return pTransferCounter->AddRef(); 1292 CPDF_RenderConfig::CPDF_RenderConfig() {
1171 } 1293 m_HalftoneLimit = 0;
1172 1294 m_RenderStepLimit = 100;
1173 CPDF_Function* pFuncs[3] = { nullptr, nullptr, nullptr }; 1295 }
1174 FX_BOOL bUniTransfer = TRUE; 1296 CPDF_RenderConfig::~CPDF_RenderConfig() {}
1175 FX_BOOL bIdentity = TRUE; 1297 CPDF_DeviceBuffer::CPDF_DeviceBuffer() {
1176 if (pObj->GetType() == PDFOBJ_ARRAY) { 1298 m_pBitmap = NULL;
1177 bUniTransfer = FALSE; 1299 m_pDevice = NULL;
1178 CPDF_Array* pArray = (CPDF_Array*)pObj; 1300 m_pContext = NULL;
1179 if (pArray->GetCount() < 3) 1301 m_pObject = NULL;
1180 return nullptr; 1302 }
1181 1303 CPDF_DeviceBuffer::~CPDF_DeviceBuffer() {
1182 for (FX_DWORD i = 0; i < 3; ++i) { 1304 delete m_pBitmap;
1183 pFuncs[2 - i] = CPDF_Function::Load(pArray->GetElementValue(i)); 1305 }
1184 if (!pFuncs[2 - i]) { 1306 FX_BOOL CPDF_DeviceBuffer::Initialize(CPDF_RenderContext* pContext,
1185 return nullptr; 1307 CFX_RenderDevice* pDevice,
1186 } 1308 FX_RECT* pRect,
1187 } 1309 const CPDF_PageObject* pObj,
1310 int max_dpi) {
1311 m_pDevice = pDevice;
1312 m_pContext = pContext;
1313 m_Rect = *pRect;
1314 m_pObject = pObj;
1315 m_Matrix.TranslateI(-pRect->left, -pRect->top);
1316 #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
1317 int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE);
1318 int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE);
1319 if (horz_size && vert_size && max_dpi) {
1320 int dpih =
1321 pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10);
1322 int dpiv =
1323 pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10);
1324 if (dpih > max_dpi) {
1325 m_Matrix.Scale((FX_FLOAT)(max_dpi) / dpih, 1.0f);
1326 }
1327 if (dpiv > max_dpi) {
1328 m_Matrix.Scale(1.0f, (FX_FLOAT)(max_dpi) / (FX_FLOAT)dpiv);
1329 }
1330 }
1331 #endif
1332 CFX_Matrix ctm = m_pDevice->GetCTM();
1333 FX_FLOAT fScaleX = FXSYS_fabs(ctm.a);
1334 FX_FLOAT fScaleY = FXSYS_fabs(ctm.d);
1335 m_Matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0);
1336 CFX_FloatRect rect(*pRect);
1337 m_Matrix.TransformRect(rect);
1338 FX_RECT bitmap_rect = rect.GetOutterRect();
1339 m_pBitmap = new CFX_DIBitmap;
1340 m_pBitmap->Create(bitmap_rect.Width(), bitmap_rect.Height(), FXDIB_Argb);
1341 return TRUE;
1342 }
1343 void CPDF_DeviceBuffer::OutputToDevice() {
1344 if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS) {
1345 if (m_Matrix.a == 1.0f && m_Matrix.d == 1.0f) {
1346 m_pDevice->SetDIBits(m_pBitmap, m_Rect.left, m_Rect.top);
1188 } else { 1347 } else {
1189 pFuncs[0] = CPDF_Function::Load(pObj); 1348 m_pDevice->StretchDIBits(m_pBitmap, m_Rect.left, m_Rect.top,
1190 if (!pFuncs[0]) { 1349 m_Rect.Width(), m_Rect.Height());
1191 return nullptr; 1350 }
1192 } 1351 } else {
1193 } 1352 CFX_DIBitmap buffer;
1194 CPDF_TransferFunc* pTransfer = new CPDF_TransferFunc; 1353 m_pDevice->CreateCompatibleBitmap(&buffer, m_pBitmap->GetWidth(),
1195 pTransfer->m_pPDFDoc = m_pPDFDoc; 1354 m_pBitmap->GetHeight());
1196 CPDF_CountedObject<CPDF_TransferFunc>* pTransferCounter = 1355 m_pContext->GetBackground(&buffer, m_pObject, NULL, &m_Matrix);
1197 new CPDF_CountedObject<CPDF_TransferFunc>(pTransfer); 1356 buffer.CompositeBitmap(0, 0, buffer.GetWidth(), buffer.GetHeight(),
1198 m_TransferFuncMap[pObj] = pTransferCounter; 1357 m_pBitmap, 0, 0);
1199 static const int kMaxOutputs = 16; 1358 m_pDevice->StretchDIBits(&buffer, m_Rect.left, m_Rect.top, m_Rect.Width(),
1200 FX_FLOAT output[kMaxOutputs]; 1359 m_Rect.Height());
1201 FXSYS_memset(output, 0, sizeof(output)); 1360 }
1202 FX_FLOAT input; 1361 }
1203 int noutput; 1362 CPDF_ScaledRenderBuffer::CPDF_ScaledRenderBuffer() {
1204 for (int v = 0; v < 256; ++v) { 1363 m_pBitmapDevice = NULL;
1205 input = (FX_FLOAT)v / 255.0f; 1364 }
1206 if (bUniTransfer) { 1365 CPDF_ScaledRenderBuffer::~CPDF_ScaledRenderBuffer() {
1207 if (pFuncs[0] && pFuncs[0]->CountOutputs() <= kMaxOutputs) 1366 delete m_pBitmapDevice;
1208 pFuncs[0]->Call(&input, 1, output, noutput); 1367 }
1209 int o = FXSYS_round(output[0] * 255); 1368 #define _FPDFAPI_IMAGESIZE_LIMIT_ (30 * 1024 * 1024)
1210 if (o != v) 1369 FX_BOOL CPDF_ScaledRenderBuffer::Initialize(CPDF_RenderContext* pContext,
1211 bIdentity = FALSE; 1370 CFX_RenderDevice* pDevice,
1212 for (int i = 0; i < 3; ++i) { 1371 FX_RECT* pRect,
1213 pTransfer->m_Samples[i * 256 + v] = o; 1372 const CPDF_PageObject* pObj,
1214 } 1373 const CPDF_RenderOptions* pOptions,
1215 } else { 1374 int max_dpi) {
1216 for (int i = 0; i < 3; ++i) { 1375 FXSYS_assert(pRect != NULL);
1217 if (pFuncs[i] && pFuncs[i]->CountOutputs() <= kMaxOutputs) { 1376 m_pDevice = pDevice;
1218 pFuncs[i]->Call(&input, 1, output, noutput); 1377 if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS) {
1219 int o = FXSYS_round(output[0] * 255); 1378 return TRUE;
1220 if (o != v) 1379 }
1221 bIdentity = FALSE; 1380 m_pContext = pContext;
1222 pTransfer->m_Samples[i * 256 + v] = o; 1381 m_Rect = *pRect;
1223 } else { 1382 m_pObject = pObj;
1224 pTransfer->m_Samples[i * 256 + v] = v; 1383 m_Matrix.TranslateI(-pRect->left, -pRect->top);
1225 } 1384 int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE);
1226 } 1385 int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE);
1227 } 1386 if (horz_size && vert_size && max_dpi) {
1228 } 1387 int dpih =
1229 for (int i = 0; i < 3; ++i) 1388 pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10);
1230 delete pFuncs[i]; 1389 int dpiv =
1231 1390 pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10);
1232 pTransfer->m_bIdentity = bIdentity; 1391 if (dpih > max_dpi) {
1233 return pTransferCounter->AddRef(); 1392 m_Matrix.Scale((FX_FLOAT)(max_dpi) / dpih, 1.0f);
1234 } 1393 }
1235 1394 if (dpiv > max_dpi) {
1236 void CPDF_DocRenderData::ReleaseTransferFunc(CPDF_Object* pObj) 1395 m_Matrix.Scale(1.0f, (FX_FLOAT)(max_dpi) / (FX_FLOAT)dpiv);
1237 { 1396 }
1238 auto it = m_TransferFuncMap.find(pObj); 1397 }
1239 if (it != m_TransferFuncMap.end()) 1398 m_pBitmapDevice = new CFX_FxgeDevice;
1240 it->second->RemoveRef(); 1399 FXDIB_Format dibFormat = FXDIB_Rgb;
1241 } 1400 int32_t bpp = 24;
1242 CPDF_RenderConfig::CPDF_RenderConfig() 1401 if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_ALPHA_OUTPUT) {
1243 { 1402 dibFormat = FXDIB_Argb;
1244 m_HalftoneLimit = 0; 1403 bpp = 32;
1245 m_RenderStepLimit = 100; 1404 }
1246 } 1405 CFX_FloatRect rect;
1247 CPDF_RenderConfig::~CPDF_RenderConfig() 1406 int32_t iWidth, iHeight, iPitch;
1248 { 1407 while (1) {
1249 } 1408 rect = *pRect;
1250 CPDF_DeviceBuffer::CPDF_DeviceBuffer()
1251 {
1252 m_pBitmap = NULL;
1253 m_pDevice = NULL;
1254 m_pContext = NULL;
1255 m_pObject = NULL;
1256 }
1257 CPDF_DeviceBuffer::~CPDF_DeviceBuffer()
1258 {
1259 delete m_pBitmap;
1260 }
1261 FX_BOOL CPDF_DeviceBuffer::Initialize(CPDF_RenderContext* pContext, CFX_RenderDe vice* pDevice, FX_RECT* pRect,
1262 const CPDF_PageObject* pObj, int max_dpi)
1263 {
1264 m_pDevice = pDevice;
1265 m_pContext = pContext;
1266 m_Rect = *pRect;
1267 m_pObject = pObj;
1268 m_Matrix.TranslateI(-pRect->left, -pRect->top);
1269 #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
1270 int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE);
1271 int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE);
1272 if (horz_size && vert_size && max_dpi) {
1273 int dpih = pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10);
1274 int dpiv = pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10);
1275 if (dpih > max_dpi) {
1276 m_Matrix.Scale((FX_FLOAT)(max_dpi) / dpih, 1.0f);
1277 }
1278 if (dpiv > max_dpi) {
1279 m_Matrix.Scale(1.0f, (FX_FLOAT)(max_dpi) / (FX_FLOAT)dpiv);
1280 }
1281 }
1282 #endif
1283 CFX_Matrix ctm = m_pDevice->GetCTM();
1284 FX_FLOAT fScaleX = FXSYS_fabs(ctm.a);
1285 FX_FLOAT fScaleY = FXSYS_fabs(ctm.d);
1286 m_Matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0);
1287 CFX_FloatRect rect(*pRect);
1288 m_Matrix.TransformRect(rect); 1409 m_Matrix.TransformRect(rect);
1289 FX_RECT bitmap_rect = rect.GetOutterRect(); 1410 FX_RECT bitmap_rect = rect.GetOutterRect();
1290 m_pBitmap = new CFX_DIBitmap; 1411 iWidth = bitmap_rect.Width();
1291 m_pBitmap->Create(bitmap_rect.Width(), bitmap_rect.Height(), FXDIB_Argb); 1412 iHeight = bitmap_rect.Height();
1292 return TRUE; 1413 iPitch = (iWidth * bpp + 31) / 32 * 4;
1293 } 1414 if (iWidth * iHeight < 1) {
1294 void CPDF_DeviceBuffer::OutputToDevice() 1415 return FALSE;
1295 { 1416 }
1296 if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS) { 1417 if (iPitch * iHeight <= _FPDFAPI_IMAGESIZE_LIMIT_ &&
1297 if (m_Matrix.a == 1.0f && m_Matrix.d == 1.0f) { 1418 m_pBitmapDevice->Create(iWidth, iHeight, dibFormat)) {
1298 m_pDevice->SetDIBits(m_pBitmap, m_Rect.left, m_Rect.top); 1419 break;
1299 } else { 1420 }
1300 m_pDevice->StretchDIBits(m_pBitmap, m_Rect.left, m_Rect.top, m_Rect. Width(), m_Rect.Height()); 1421 m_Matrix.Scale(0.5f, 0.5f);
1301 } 1422 }
1302 } else { 1423 m_pContext->GetBackground(m_pBitmapDevice->GetBitmap(), m_pObject, pOptions,
1303 CFX_DIBitmap buffer; 1424 &m_Matrix);
1304 m_pDevice->CreateCompatibleBitmap(&buffer, m_pBitmap->GetWidth(), m_pBit map->GetHeight()); 1425 return TRUE;
1305 m_pContext->GetBackground(&buffer, m_pObject, NULL, &m_Matrix); 1426 }
1306 buffer.CompositeBitmap(0, 0, buffer.GetWidth(), buffer.GetHeight(), m_pB itmap, 0, 0); 1427 void CPDF_ScaledRenderBuffer::OutputToDevice() {
1307 m_pDevice->StretchDIBits(&buffer, m_Rect.left, m_Rect.top, m_Rect.Width( ), m_Rect.Height()); 1428 if (m_pBitmapDevice) {
1308 } 1429 m_pDevice->StretchDIBits(m_pBitmapDevice->GetBitmap(), m_Rect.left,
1309 } 1430 m_Rect.top, m_Rect.Width(), m_Rect.Height());
1310 CPDF_ScaledRenderBuffer::CPDF_ScaledRenderBuffer() 1431 }
1311 { 1432 }
1312 m_pBitmapDevice = NULL; 1433 FX_BOOL IPDF_OCContext::CheckObjectVisible(const CPDF_PageObject* pObj) {
1313 } 1434 const CPDF_ContentMarkData* pData = pObj->m_ContentMark;
1314 CPDF_ScaledRenderBuffer::~CPDF_ScaledRenderBuffer() 1435 int nItems = pData->CountItems();
1315 { 1436 for (int i = 0; i < nItems; i++) {
1316 delete m_pBitmapDevice; 1437 CPDF_ContentMarkItem& item = pData->GetItem(i);
1317 } 1438 if (item.GetName() == FX_BSTRC("OC") &&
1318 #define _FPDFAPI_IMAGESIZE_LIMIT_» (30 * 1024 * 1024) 1439 item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict) {
1319 FX_BOOL CPDF_ScaledRenderBuffer::Initialize(CPDF_RenderContext* pContext, CFX_Re nderDevice* pDevice, FX_RECT* pRect, 1440 CPDF_Dictionary* pOCG = (CPDF_Dictionary*)item.GetParam();
1320 const CPDF_PageObject* pObj, const CPDF_RenderOptions *pOptions, int max _dpi) 1441 if (!CheckOCGVisible(pOCG)) {
1321 { 1442 return FALSE;
1322 FXSYS_assert(pRect != NULL); 1443 }
1323 m_pDevice = pDevice; 1444 }
1324 if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS) { 1445 }
1325 return TRUE; 1446 return TRUE;
1326 } 1447 }
1327 m_pContext = pContext;
1328 m_Rect = *pRect;
1329 m_pObject = pObj;
1330 m_Matrix.TranslateI(-pRect->left, -pRect->top);
1331 int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE);
1332 int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE);
1333 if (horz_size && vert_size && max_dpi) {
1334 int dpih = pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10);
1335 int dpiv = pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10);
1336 if (dpih > max_dpi) {
1337 m_Matrix.Scale((FX_FLOAT)(max_dpi) / dpih, 1.0f);
1338 }
1339 if (dpiv > max_dpi) {
1340 m_Matrix.Scale(1.0f, (FX_FLOAT)(max_dpi) / (FX_FLOAT)dpiv);
1341 }
1342 }
1343 m_pBitmapDevice = new CFX_FxgeDevice;
1344 FXDIB_Format dibFormat = FXDIB_Rgb;
1345 int32_t bpp = 24;
1346 if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_ALPHA_OUTPUT) {
1347 dibFormat = FXDIB_Argb;
1348 bpp = 32;
1349 }
1350 CFX_FloatRect rect;
1351 int32_t iWidth, iHeight, iPitch;
1352 while (1) {
1353 rect = *pRect;
1354 m_Matrix.TransformRect(rect);
1355 FX_RECT bitmap_rect = rect.GetOutterRect();
1356 iWidth = bitmap_rect.Width();
1357 iHeight = bitmap_rect.Height();
1358 iPitch = (iWidth * bpp + 31) / 32 * 4;
1359 if (iWidth * iHeight < 1) {
1360 return FALSE;
1361 }
1362 if (iPitch * iHeight <= _FPDFAPI_IMAGESIZE_LIMIT_ &&
1363 m_pBitmapDevice->Create(iWidth, iHeight, dibFormat)) {
1364 break;
1365 }
1366 m_Matrix.Scale(0.5f, 0.5f);
1367 }
1368 m_pContext->GetBackground(m_pBitmapDevice->GetBitmap(), m_pObject, pOptions, &m_Matrix);
1369 return TRUE;
1370 }
1371 void CPDF_ScaledRenderBuffer::OutputToDevice()
1372 {
1373 if (m_pBitmapDevice) {
1374 m_pDevice->StretchDIBits(m_pBitmapDevice->GetBitmap(), m_Rect.left, m_Re ct.top, m_Rect.Width(), m_Rect.Height());
1375 }
1376 }
1377 FX_BOOL IPDF_OCContext::CheckObjectVisible(const CPDF_PageObject* pObj)
1378 {
1379 const CPDF_ContentMarkData* pData = pObj->m_ContentMark;
1380 int nItems = pData->CountItems();
1381 for (int i = 0; i < nItems; i ++) {
1382 CPDF_ContentMarkItem& item = pData->GetItem(i);
1383 if (item.GetName() == FX_BSTRC("OC") && item.GetParamType() == CPDF_Cont entMarkItem::PropertiesDict) {
1384 CPDF_Dictionary* pOCG = (CPDF_Dictionary*)item.GetParam();
1385 if (!CheckOCGVisible(pOCG)) {
1386 return FALSE;
1387 }
1388 }
1389 }
1390 return TRUE;
1391 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698