OLD | NEW |
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 } | |
OLD | NEW |