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 "../../core/include/fxcodec/fx_codec.h" | 7 #include "../../core/include/fxcodec/fx_codec.h" |
8 #include "../../core/include/fxcrt/fx_safe_types.h" | 8 #include "../../core/include/fxcrt/fx_safe_types.h" |
9 #include "../../public/fpdf_ext.h" | 9 #include "../../public/fpdf_ext.h" |
10 #include "../../public/fpdf_progressive.h" | 10 #include "../../public/fpdf_progressive.h" |
11 #include "../../public/fpdfview.h" | 11 #include "../../public/fpdfview.h" |
12 #include "../../third_party/base/nonstd_unique_ptr.h" | 12 #include "../../third_party/base/nonstd_unique_ptr.h" |
13 #include "../../third_party/base/numerics/safe_conversions_impl.h" | 13 #include "../../third_party/base/numerics/safe_conversions_impl.h" |
14 #include "../include/fsdk_define.h" | 14 #include "../include/fsdk_define.h" |
15 #include "../include/fsdk_mgr.h" | 15 #include "../include/fsdk_mgr.h" |
16 #include "../include/fsdk_rendercontext.h" | 16 #include "../include/fsdk_rendercontext.h" |
17 | 17 |
18 CPDF_CustomAccess::CPDF_CustomAccess(FPDF_FILEACCESS* pFileAccess) | 18 CPDF_CustomAccess::CPDF_CustomAccess(FPDF_FILEACCESS* pFileAccess) { |
19 { | 19 if (pFileAccess) |
20 if (pFileAccess) | 20 m_FileAccess = *pFileAccess; |
21 m_FileAccess = *pFileAccess; | |
22 } | 21 } |
23 | 22 |
24 FX_BOOL CPDF_CustomAccess::ReadBlock(void* buffer, FX_FILESIZE offset, size_t si
ze) | 23 FX_BOOL CPDF_CustomAccess::ReadBlock(void* buffer, |
25 { | 24 FX_FILESIZE offset, |
26 if (offset < 0) { | 25 size_t size) { |
27 return FALSE; | 26 if (offset < 0) { |
28 } | 27 return FALSE; |
29 FX_SAFE_FILESIZE newPos = pdfium::base::checked_cast<FX_FILESIZE, size_t>(si
ze); | 28 } |
30 newPos += offset; | 29 FX_SAFE_FILESIZE newPos = |
31 if (!newPos.IsValid() || newPos.ValueOrDie() > m_FileAccess.m_FileLen) { | 30 pdfium::base::checked_cast<FX_FILESIZE, size_t>(size); |
32 return FALSE; | 31 newPos += offset; |
33 } | 32 if (!newPos.IsValid() || newPos.ValueOrDie() > m_FileAccess.m_FileLen) { |
34 return m_FileAccess.m_GetBlock(m_FileAccess.m_Param, offset,(uint8_t*) buffe
r, size); | 33 return FALSE; |
| 34 } |
| 35 return m_FileAccess.m_GetBlock(m_FileAccess.m_Param, offset, (uint8_t*)buffer, |
| 36 size); |
35 } | 37 } |
36 | 38 |
37 //0 bit: FPDF_POLICY_MACHINETIME_ACCESS | 39 // 0 bit: FPDF_POLICY_MACHINETIME_ACCESS |
38 static FX_DWORD foxit_sandbox_policy = 0xFFFFFFFF; | 40 static FX_DWORD foxit_sandbox_policy = 0xFFFFFFFF; |
39 | 41 |
40 void FSDK_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enable) | 42 void FSDK_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enable) { |
41 { | 43 switch (policy) { |
42 switch(policy) | 44 case FPDF_POLICY_MACHINETIME_ACCESS: { |
43 { | 45 if (enable) |
44 case FPDF_POLICY_MACHINETIME_ACCESS: | 46 foxit_sandbox_policy |= 0x01; |
45 { | 47 else |
46 if(enable) | 48 foxit_sandbox_policy &= 0xFFFFFFFE; |
47 foxit_sandbox_policy |= 0x01; | 49 } break; |
48 else | |
49 foxit_sandbox_policy &= 0xFFFFFFFE; | |
50 } | |
51 break; | |
52 default: | 50 default: |
53 break; | 51 break; |
54 } | 52 } |
55 } | 53 } |
56 | 54 |
57 FPDF_BOOL FSDK_IsSandBoxPolicyEnabled(FPDF_DWORD policy) | 55 FPDF_BOOL FSDK_IsSandBoxPolicyEnabled(FPDF_DWORD policy) { |
58 { | 56 switch (policy) { |
59 switch(policy) | |
60 { | |
61 case FPDF_POLICY_MACHINETIME_ACCESS: | 57 case FPDF_POLICY_MACHINETIME_ACCESS: |
62 return (foxit_sandbox_policy & 0x01) ? TRUE : FALSE; | 58 return (foxit_sandbox_policy & 0x01) ? TRUE : FALSE; |
63 default: | 59 default: |
64 return FALSE; | 60 return FALSE; |
65 } | 61 } |
66 } | 62 } |
67 | 63 |
68 #ifndef _T | 64 #ifndef _T |
69 #define _T(x) x | 65 #define _T(x) x |
70 #endif | 66 #endif |
71 | 67 |
72 CCodec_ModuleMgr* g_pCodecModule = nullptr; | 68 CCodec_ModuleMgr* g_pCodecModule = nullptr; |
73 | 69 |
74 #if _FX_OS_ == _FX_LINUX_EMBEDDED_ | 70 #if _FX_OS_ == _FX_LINUX_EMBEDDED_ |
75 class CFontMapper : public IPDF_FontMapper | 71 class CFontMapper : public IPDF_FontMapper { |
76 { | 72 public: |
77 public: | 73 CFontMapper(); |
78 CFontMapper(); | 74 virtual ~CFontMapper(); |
79 virtual ~CFontMapper(); | 75 |
80 | 76 virtual FT_Face FindSubstFont( |
81 virtual FT_Face FindSubstFont( | 77 CPDF_Document* pDoc, // [IN] The PDF document |
82 CPDF_Document* pDoc, // [IN] The PDF
document | 78 const CFX_ByteString& face_name, // [IN] Original name |
83 const CFX_ByteString& face_name, // [IN] Original
name | 79 FX_BOOL bTrueType, // [IN] TrueType or Type1 |
84 FX_BOOL bTrueType, // [IN] TrueType
or Type1 | 80 FX_DWORD flags, // [IN] PDF font flags (see PDF Reference section 5.7.1) |
85 FX_DWORD flags, // [IN] PDF font
flags (see PDF Reference section 5.7.1) | 81 int font_weight, // [IN] original font weight. 0 for not specified |
86 int font_weight, // [IN] original
font weight. 0 for not specified | 82 int CharsetCP, // [IN] code page for charset (see Win32 GetACP()) |
87 int CharsetCP, // [IN] code pag
e for charset (see Win32 GetACP()) | 83 FX_BOOL bVertical, |
88 FX_BOOL bVertical, | 84 CPDF_SubstFont* pSubstFont // [OUT] Subst font data |
89 CPDF_SubstFont* pSubstFont // [OUT] Subst f
ont data | 85 ); |
90 ); | 86 |
91 | 87 FT_Face m_SysFace; |
92 FT_Face m_SysFace; | |
93 }; | 88 }; |
94 | 89 |
95 CFontMapper* g_pFontMapper = NULL; | 90 CFontMapper* g_pFontMapper = NULL; |
96 #endif // #if _FX_OS_ == _FX_LINUX_EMBEDDED_ | 91 #endif // #if _FX_OS_ == _FX_LINUX_EMBEDDED_ |
97 | 92 |
98 DLLEXPORT void STDCALL FPDF_InitLibrary() | 93 DLLEXPORT void STDCALL FPDF_InitLibrary() { |
99 { | 94 g_pCodecModule = new CCodec_ModuleMgr(); |
100 g_pCodecModule = new CCodec_ModuleMgr(); | 95 |
101 | 96 CFX_GEModule::Create(); |
102 CFX_GEModule::Create(); | 97 CFX_GEModule::Get()->SetCodecModule(g_pCodecModule); |
103 CFX_GEModule::Get()->SetCodecModule(g_pCodecModule); | 98 |
104 | 99 CPDF_ModuleMgr::Create(); |
105 CPDF_ModuleMgr::Create(); | 100 CPDF_ModuleMgr::Get()->SetCodecModule(g_pCodecModule); |
106 CPDF_ModuleMgr::Get()->SetCodecModule(g_pCodecModule); | 101 CPDF_ModuleMgr::Get()->InitPageModule(); |
107 CPDF_ModuleMgr::Get()->InitPageModule(); | 102 CPDF_ModuleMgr::Get()->InitRenderModule(); |
108 CPDF_ModuleMgr::Get()->InitRenderModule(); | 103 CPDF_ModuleMgr* pModuleMgr = CPDF_ModuleMgr::Get(); |
109 CPDF_ModuleMgr * pModuleMgr = CPDF_ModuleMgr::Get(); | 104 if (pModuleMgr) { |
110 if ( pModuleMgr ) | 105 pModuleMgr->LoadEmbeddedGB1CMaps(); |
111 { | 106 pModuleMgr->LoadEmbeddedJapan1CMaps(); |
112 pModuleMgr->LoadEmbeddedGB1CMaps(); | 107 pModuleMgr->LoadEmbeddedCNS1CMaps(); |
113 pModuleMgr->LoadEmbeddedJapan1CMaps(); | 108 pModuleMgr->LoadEmbeddedKorea1CMaps(); |
114 pModuleMgr->LoadEmbeddedCNS1CMaps(); | 109 } |
115 pModuleMgr->LoadEmbeddedKorea1CMaps(); | 110 } |
116 } | 111 |
117 } | 112 DLLEXPORT void STDCALL FPDF_DestroyLibrary() { |
118 | |
119 | |
120 DLLEXPORT void STDCALL FPDF_DestroyLibrary() | |
121 { | |
122 | |
123 #if _FX_OS_ == _FX_LINUX_EMBEDDED_ | 113 #if _FX_OS_ == _FX_LINUX_EMBEDDED_ |
124 delete g_pFontMapper; | 114 delete g_pFontMapper; |
125 g_pFontMapper = nullptr; | 115 g_pFontMapper = nullptr; |
126 #endif | 116 #endif |
127 CPDF_ModuleMgr::Destroy(); | 117 CPDF_ModuleMgr::Destroy(); |
128 CFX_GEModule::Destroy(); | 118 CFX_GEModule::Destroy(); |
129 delete g_pCodecModule; | 119 delete g_pCodecModule; |
130 g_pCodecModule = nullptr; | 120 g_pCodecModule = nullptr; |
131 } | 121 } |
132 | 122 |
133 #ifndef _WIN32 | 123 #ifndef _WIN32 |
134 int g_LastError; | 124 int g_LastError; |
135 void SetLastError(int err) | 125 void SetLastError(int err) { |
136 { | 126 g_LastError = err; |
137 g_LastError = err; | 127 } |
138 } | 128 |
139 | 129 int GetLastError() { |
140 int GetLastError() | 130 return g_LastError; |
141 { | |
142 return g_LastError; | |
143 } | 131 } |
144 #endif | 132 #endif |
145 | 133 |
146 void ProcessParseError(FX_DWORD err_code) | 134 void ProcessParseError(FX_DWORD err_code) { |
147 { | 135 // Translate FPDFAPI error code to FPDFVIEW error code |
148 // Translate FPDFAPI error code to FPDFVIEW error code | 136 switch (err_code) { |
149 switch (err_code) { | 137 case PDFPARSE_ERROR_FILE: |
150 case PDFPARSE_ERROR_FILE: | 138 err_code = FPDF_ERR_FILE; |
151 err_code = FPDF_ERR_FILE; | 139 break; |
152 break; | 140 case PDFPARSE_ERROR_FORMAT: |
153 case PDFPARSE_ERROR_FORMAT: | 141 err_code = FPDF_ERR_FORMAT; |
154 err_code = FPDF_ERR_FORMAT; | 142 break; |
155 break; | 143 case PDFPARSE_ERROR_PASSWORD: |
156 case PDFPARSE_ERROR_PASSWORD: | 144 err_code = FPDF_ERR_PASSWORD; |
157 err_code = FPDF_ERR_PASSWORD; | 145 break; |
158 break; | 146 case PDFPARSE_ERROR_HANDLER: |
159 case PDFPARSE_ERROR_HANDLER: | 147 err_code = FPDF_ERR_SECURITY; |
160 err_code = FPDF_ERR_SECURITY; | 148 break; |
161 break; | 149 } |
| 150 SetLastError(err_code); |
| 151 } |
| 152 |
| 153 DLLEXPORT void STDCALL FPDF_SetSandBoxPolicy(FPDF_DWORD policy, |
| 154 FPDF_BOOL enable) { |
| 155 return FSDK_SetSandBoxPolicy(policy, enable); |
| 156 } |
| 157 |
| 158 DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadDocument(FPDF_STRING file_path, |
| 159 FPDF_BYTESTRING password) { |
| 160 CPDF_Parser* pParser = new CPDF_Parser; |
| 161 pParser->SetPassword(password); |
| 162 |
| 163 FX_DWORD err_code = pParser->StartParse((const FX_CHAR*)file_path); |
| 164 if (err_code) { |
| 165 delete pParser; |
| 166 ProcessParseError(err_code); |
| 167 return NULL; |
| 168 } |
| 169 return pParser->GetDocument(); |
| 170 } |
| 171 |
| 172 extern void CheckUnSupportError(CPDF_Document* pDoc, FX_DWORD err_code); |
| 173 |
| 174 class CMemFile final : public IFX_FileRead { |
| 175 public: |
| 176 CMemFile(uint8_t* pBuf, FX_FILESIZE size) : m_pBuf(pBuf), m_size(size) {} |
| 177 |
| 178 virtual void Release() { delete this; } |
| 179 virtual FX_FILESIZE GetSize() { return m_size; } |
| 180 virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) { |
| 181 if (offset < 0) { |
| 182 return FALSE; |
162 } | 183 } |
163 SetLastError(err_code); | 184 FX_SAFE_FILESIZE newPos = |
164 } | 185 pdfium::base::checked_cast<FX_FILESIZE, size_t>(size); |
165 | 186 newPos += offset; |
166 DLLEXPORT void STDCALL FPDF_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enabl
e) | 187 if (!newPos.IsValid() || newPos.ValueOrDie() > (FX_DWORD)m_size) { |
167 { | 188 return FALSE; |
168 return FSDK_SetSandBoxPolicy(policy, enable); | |
169 } | |
170 | |
171 DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadDocument(FPDF_STRING file_path, FPDF_BY
TESTRING password) | |
172 { | |
173 CPDF_Parser* pParser = new CPDF_Parser; | |
174 pParser->SetPassword(password); | |
175 | |
176 FX_DWORD err_code = pParser->StartParse((const FX_CHAR*)file_path); | |
177 if (err_code) { | |
178 delete pParser; | |
179 ProcessParseError(err_code); | |
180 return NULL; | |
181 } | 189 } |
182 return pParser->GetDocument(); | 190 FXSYS_memcpy(buffer, m_pBuf + offset, size); |
183 } | 191 return TRUE; |
184 | 192 } |
185 extern void CheckUnSupportError(CPDF_Document * pDoc, FX_DWORD err_code); | 193 |
186 | 194 private: |
187 class CMemFile final: public IFX_FileRead | 195 uint8_t* m_pBuf; |
188 { | 196 FX_FILESIZE m_size; |
189 public: | |
190 CMemFile(uint8_t* pBuf, FX_FILESIZE size):m_pBuf(pBuf),m_size(size) {} | |
191 | |
192 virtual void Release() {delete this;} | |
193 virtual FX_FILESIZE GetSize() {return m_size;} | |
194 virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t s
ize) | |
195 { | |
196 if (offset < 0) { | |
197 return FALSE; | |
198 } | |
199 FX_SAFE_FILESIZE newPos = pdfium::base::checked_cast<FX_FILESIZE, si
ze_t>(size); | |
200 newPos += offset; | |
201 if (!newPos.IsValid() || newPos.ValueOrDie() > (FX_DWORD)m_size) { | |
202 return FALSE; | |
203 } | |
204 FXSYS_memcpy(buffer, m_pBuf+offset, size); | |
205 return TRUE; | |
206 } | |
207 private: | |
208 uint8_t* m_pBuf; | |
209 FX_FILESIZE m_size; | |
210 }; | 197 }; |
211 DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadMemDocument(const void* data_buf, int s
ize, FPDF_BYTESTRING password) | 198 DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadMemDocument(const void* data_buf, |
212 { | 199 int size, |
213 CPDF_Parser* pParser = new CPDF_Parser; | 200 FPDF_BYTESTRING password) { |
214 pParser->SetPassword(password); | 201 CPDF_Parser* pParser = new CPDF_Parser; |
215 CMemFile* pMemFile = new CMemFile((uint8_t*)data_buf, size); | 202 pParser->SetPassword(password); |
216 FX_DWORD err_code = pParser->StartParse(pMemFile); | 203 CMemFile* pMemFile = new CMemFile((uint8_t*)data_buf, size); |
217 if (err_code) { | 204 FX_DWORD err_code = pParser->StartParse(pMemFile); |
218 delete pParser; | 205 if (err_code) { |
219 ProcessParseError(err_code); | 206 delete pParser; |
220 return NULL; | 207 ProcessParseError(err_code); |
221 } | 208 return NULL; |
222 CPDF_Document * pDoc = NULL; | 209 } |
223 pDoc = pParser?pParser->GetDocument():NULL; | 210 CPDF_Document* pDoc = NULL; |
224 CheckUnSupportError(pDoc, err_code); | 211 pDoc = pParser ? pParser->GetDocument() : NULL; |
225 return pParser->GetDocument(); | 212 CheckUnSupportError(pDoc, err_code); |
226 } | 213 return pParser->GetDocument(); |
227 | 214 } |
228 DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadCustomDocument(FPDF_FILEACCESS* pFileAc
cess, FPDF_BYTESTRING password) | 215 |
229 { | 216 DLLEXPORT FPDF_DOCUMENT STDCALL |
230 CPDF_Parser* pParser = new CPDF_Parser; | 217 FPDF_LoadCustomDocument(FPDF_FILEACCESS* pFileAccess, |
231 pParser->SetPassword(password); | 218 FPDF_BYTESTRING password) { |
232 CPDF_CustomAccess* pFile = new CPDF_CustomAccess(pFileAccess); | 219 CPDF_Parser* pParser = new CPDF_Parser; |
233 FX_DWORD err_code = pParser->StartParse(pFile); | 220 pParser->SetPassword(password); |
234 if (err_code) { | 221 CPDF_CustomAccess* pFile = new CPDF_CustomAccess(pFileAccess); |
235 delete pParser; | 222 FX_DWORD err_code = pParser->StartParse(pFile); |
236 ProcessParseError(err_code); | 223 if (err_code) { |
237 return NULL; | 224 delete pParser; |
238 } | 225 ProcessParseError(err_code); |
239 CPDF_Document * pDoc = NULL; | 226 return NULL; |
240 pDoc = pParser?pParser->GetDocument():NULL; | 227 } |
241 CheckUnSupportError(pDoc, err_code); | 228 CPDF_Document* pDoc = NULL; |
242 return pParser->GetDocument(); | 229 pDoc = pParser ? pParser->GetDocument() : NULL; |
243 } | 230 CheckUnSupportError(pDoc, err_code); |
244 | 231 return pParser->GetDocument(); |
245 DLLEXPORT FPDF_BOOL STDCALL FPDF_GetFileVersion(FPDF_DOCUMENT doc, int* fileVers
ion) | 232 } |
246 { | 233 |
247 if(!doc||!fileVersion) return FALSE; | 234 DLLEXPORT FPDF_BOOL STDCALL FPDF_GetFileVersion(FPDF_DOCUMENT doc, |
248 *fileVersion = 0; | 235 int* fileVersion) { |
249 CPDF_Document* pDoc = (CPDF_Document*)doc; | 236 if (!doc || !fileVersion) |
250 CPDF_Parser* pParser = (CPDF_Parser*)pDoc->GetParser(); | 237 return FALSE; |
251 if(!pParser) | 238 *fileVersion = 0; |
252 return FALSE; | 239 CPDF_Document* pDoc = (CPDF_Document*)doc; |
253 *fileVersion = pParser->GetFileVersion(); | 240 CPDF_Parser* pParser = (CPDF_Parser*)pDoc->GetParser(); |
254 return TRUE; | 241 if (!pParser) |
255 } | 242 return FALSE; |
256 | 243 *fileVersion = pParser->GetFileVersion(); |
257 // jabdelmalek: changed return type from FX_DWORD to build on Linux (and match h
eader). | 244 return TRUE; |
258 DLLEXPORT unsigned long STDCALL FPDF_GetDocPermissions(FPDF_DOCUMENT document) | 245 } |
259 { | 246 |
260 if (document == NULL) return 0; | 247 // jabdelmalek: changed return type from FX_DWORD to build on Linux (and match |
261 CPDF_Document*pDoc = (CPDF_Document*)document; | 248 // header). |
262 CPDF_Parser* pParser = (CPDF_Parser*)pDoc->GetParser(); | 249 DLLEXPORT unsigned long STDCALL FPDF_GetDocPermissions(FPDF_DOCUMENT document) { |
263 CPDF_Dictionary* pDict = pParser->GetEncryptDict(); | 250 if (document == NULL) |
264 if (pDict == NULL) return (FX_DWORD)-1; | 251 return 0; |
265 | 252 CPDF_Document* pDoc = (CPDF_Document*)document; |
266 return pDict->GetInteger("P"); | 253 CPDF_Parser* pParser = (CPDF_Parser*)pDoc->GetParser(); |
267 } | 254 CPDF_Dictionary* pDict = pParser->GetEncryptDict(); |
268 | 255 if (pDict == NULL) |
269 DLLEXPORT int STDCALL FPDF_GetSecurityHandlerRevision(FPDF_DOCUMENT document) | 256 return (FX_DWORD)-1; |
270 { | 257 |
271 if (document == NULL) return -1; | 258 return pDict->GetInteger("P"); |
272 CPDF_Document*pDoc = (CPDF_Document*)document; | 259 } |
273 CPDF_Parser* pParser = (CPDF_Parser*)pDoc->GetParser(); | 260 |
274 CPDF_Dictionary* pDict = pParser->GetEncryptDict(); | 261 DLLEXPORT int STDCALL FPDF_GetSecurityHandlerRevision(FPDF_DOCUMENT document) { |
275 if (pDict == NULL) return -1; | 262 if (document == NULL) |
276 | 263 return -1; |
277 return pDict->GetInteger("R"); | 264 CPDF_Document* pDoc = (CPDF_Document*)document; |
278 } | 265 CPDF_Parser* pParser = (CPDF_Parser*)pDoc->GetParser(); |
279 | 266 CPDF_Dictionary* pDict = pParser->GetEncryptDict(); |
280 DLLEXPORT int STDCALL FPDF_GetPageCount(FPDF_DOCUMENT document) | 267 if (pDict == NULL) |
281 { | 268 return -1; |
282 if (document == NULL) return 0; | 269 |
283 return ((CPDF_Document*)document)->GetPageCount(); | 270 return pDict->GetInteger("R"); |
284 } | 271 } |
285 | 272 |
286 DLLEXPORT FPDF_PAGE STDCALL FPDF_LoadPage(FPDF_DOCUMENT document, int page_index
) | 273 DLLEXPORT int STDCALL FPDF_GetPageCount(FPDF_DOCUMENT document) { |
287 { | 274 if (document == NULL) |
288 if (document == NULL) return NULL; | 275 return 0; |
289 if (page_index < 0 || page_index >= FPDF_GetPageCount(document)) return NULL
; | 276 return ((CPDF_Document*)document)->GetPageCount(); |
290 | 277 } |
291 CPDF_Document* pDoc = (CPDF_Document*)document; | 278 |
292 if (pDoc == NULL) return NULL; | 279 DLLEXPORT FPDF_PAGE STDCALL FPDF_LoadPage(FPDF_DOCUMENT document, |
293 CPDF_Dictionary* pDict = pDoc->GetPage(page_index); | 280 int page_index) { |
294 if (pDict == NULL) return NULL; | 281 if (document == NULL) |
295 CPDF_Page* pPage = new CPDF_Page; | 282 return NULL; |
296 pPage->Load(pDoc, pDict); | 283 if (page_index < 0 || page_index >= FPDF_GetPageCount(document)) |
297 pPage->ParseContent(); | 284 return NULL; |
298 return pPage; | 285 |
299 } | 286 CPDF_Document* pDoc = (CPDF_Document*)document; |
300 | 287 if (pDoc == NULL) |
301 DLLEXPORT double STDCALL FPDF_GetPageWidth(FPDF_PAGE page) | 288 return NULL; |
302 { | 289 CPDF_Dictionary* pDict = pDoc->GetPage(page_index); |
303 if (!page) | 290 if (pDict == NULL) |
304 return 0.0; | 291 return NULL; |
305 return ((CPDF_Page*)page)->GetPageWidth(); | 292 CPDF_Page* pPage = new CPDF_Page; |
306 } | 293 pPage->Load(pDoc, pDict); |
307 | 294 pPage->ParseContent(); |
308 DLLEXPORT double STDCALL FPDF_GetPageHeight(FPDF_PAGE page) | 295 return pPage; |
309 { | 296 } |
310 if (!page) return 0.0; | 297 |
311 return ((CPDF_Page*)page)->GetPageHeight(); | 298 DLLEXPORT double STDCALL FPDF_GetPageWidth(FPDF_PAGE page) { |
312 } | 299 if (!page) |
313 | 300 return 0.0; |
314 void DropContext(void* data) | 301 return ((CPDF_Page*)page)->GetPageWidth(); |
315 { | 302 } |
316 delete (CRenderContext*)data; | 303 |
| 304 DLLEXPORT double STDCALL FPDF_GetPageHeight(FPDF_PAGE page) { |
| 305 if (!page) |
| 306 return 0.0; |
| 307 return ((CPDF_Page*)page)->GetPageHeight(); |
| 308 } |
| 309 |
| 310 void DropContext(void* data) { |
| 311 delete (CRenderContext*)data; |
317 } | 312 } |
318 | 313 |
319 #if defined(_DEBUG) || defined(DEBUG) | 314 #if defined(_DEBUG) || defined(DEBUG) |
320 #define DEBUG_TRACE | 315 #define DEBUG_TRACE |
321 #endif | 316 #endif |
322 | 317 |
323 #if defined(_WIN32) | 318 #if defined(_WIN32) |
324 DLLEXPORT void STDCALL FPDF_RenderPage(HDC dc, FPDF_PAGE page, int start_x, int
start_y, int size_x, int size_y, | 319 DLLEXPORT void STDCALL FPDF_RenderPage(HDC dc, |
325 int rotate, int flags) | 320 FPDF_PAGE page, |
326 { | 321 int start_x, |
327 if (page==NULL) return; | 322 int start_y, |
328 CPDF_Page* pPage = (CPDF_Page*)page; | 323 int size_x, |
329 | 324 int size_y, |
330 CRenderContext* pContext = new CRenderContext; | 325 int rotate, |
331 pPage->SetPrivateData((void*)1, pContext, DropContext); | 326 int flags) { |
| 327 if (page == NULL) |
| 328 return; |
| 329 CPDF_Page* pPage = (CPDF_Page*)page; |
| 330 |
| 331 CRenderContext* pContext = new CRenderContext; |
| 332 pPage->SetPrivateData((void*)1, pContext, DropContext); |
332 | 333 |
333 #ifndef _WIN32_WCE | 334 #ifndef _WIN32_WCE |
334 CFX_DIBitmap* pBitmap = NULL; | 335 CFX_DIBitmap* pBitmap = NULL; |
335 FX_BOOL bBackgroundAlphaNeeded=FALSE; | 336 FX_BOOL bBackgroundAlphaNeeded = FALSE; |
336 bBackgroundAlphaNeeded = pPage->BackgroundAlphaNeeded(); | 337 bBackgroundAlphaNeeded = pPage->BackgroundAlphaNeeded(); |
337 if (bBackgroundAlphaNeeded) | 338 if (bBackgroundAlphaNeeded) { |
338 { | 339 pBitmap = new CFX_DIBitmap; |
339 | 340 pBitmap->Create(size_x, size_y, FXDIB_Argb); |
340 pBitmap = new CFX_DIBitmap; | 341 pBitmap->Clear(0x00ffffff); |
341 pBitmap->Create(size_x, size_y, FXDIB_Argb); | |
342 pBitmap->Clear(0x00ffffff); | |
343 #ifdef _SKIA_SUPPORT_ | |
344 pContext->m_pDevice = new CFX_SkiaDevice; | |
345 ((CFX_SkiaDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)pBitmap); | |
346 #else | |
347 pContext->m_pDevice = new CFX_FxgeDevice; | |
348 ((CFX_FxgeDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)pBitmap); | |
349 #endif | |
350 } | |
351 else | |
352 pContext->m_pDevice = new CFX_WindowsDevice(dc); | |
353 | |
354 FPDF_RenderPage_Retail(pContext, page, start_x, start_y, size_x, size_y, | |
355 rotate, flags, TRUE, NULL); | |
356 | |
357 if (bBackgroundAlphaNeeded) | |
358 { | |
359 if (pBitmap) | |
360 { | |
361 CFX_WindowsDevice WinDC(dc); | |
362 | |
363 if (WinDC.GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) | |
364 { | |
365 CFX_DIBitmap* pDst = new CFX_DIBitmap; | |
366 int pitch = pBitmap->GetPitch(); | |
367 pDst->Create(size_x, size_y, FXDIB_Rgb32); | |
368 FXSYS_memset(pDst->GetBuffer(), -1, pitch*size_y); | |
369 pDst->CompositeBitmap(0, 0, size_x, size_y, pBitmap, 0, 0, FXDIB
_BLEND_NORMAL, NULL, FALSE, NULL); | |
370 WinDC.StretchDIBits(pDst,0,0,size_x,size_y); | |
371 delete pDst; | |
372 } | |
373 else | |
374 WinDC.SetDIBits(pBitmap,0,0); | |
375 | |
376 } | |
377 } | |
378 #else | |
379 // get clip region | |
380 RECT rect, cliprect; | |
381 rect.left = start_x; | |
382 rect.top = start_y; | |
383 rect.right = start_x + size_x; | |
384 rect.bottom = start_y + size_y; | |
385 GetClipBox(dc, &cliprect); | |
386 IntersectRect(&rect, &rect, &cliprect); | |
387 int width = rect.right - rect.left; | |
388 int height = rect.bottom - rect.top; | |
389 | |
390 #ifdef DEBUG_TRACE | |
391 { | |
392 char str[128]; | |
393 memset(str, 0, sizeof(str)); | |
394 FXSYS_snprintf(str, sizeof(str) - 1, "Rendering DIB %d x %d", width, hei
ght); | |
395 CPDF_ModuleMgr::Get()->ReportError(999, str); | |
396 } | |
397 #endif | |
398 | |
399 // Create a DIB section | |
400 LPVOID pBuffer; | |
401 BITMAPINFOHEADER bmih; | |
402 FXSYS_memset(&bmih, 0, sizeof bmih); | |
403 bmih.biSize = sizeof bmih; | |
404 bmih.biBitCount = 24; | |
405 bmih.biHeight = -height; | |
406 bmih.biPlanes = 1; | |
407 bmih.biWidth = width; | |
408 pContext->m_hBitmap = CreateDIBSection(dc, (BITMAPINFO*)&bmih, DIB_RGB_COLOR
S, &pBuffer, NULL, 0); | |
409 if (pContext->m_hBitmap == NULL) { | |
410 #if defined(DEBUG) || defined(_DEBUG) | |
411 char str[128]; | |
412 memset(str, 0, sizeof(str)); | |
413 FXSYS_snprintf(str, sizeof(str) - 1, "Error CreateDIBSection: %d x %d, e
rror code = %d", width, height, GetLastError()); | |
414 CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, str); | |
415 #else | |
416 CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, NULL); | |
417 #endif | |
418 } | |
419 FXSYS_memset(pBuffer, 0xff, height*((width*3+3)/4*4)); | |
420 | |
421 #ifdef DEBUG_TRACE | |
422 { | |
423 CPDF_ModuleMgr::Get()->ReportError(999, "DIBSection created"); | |
424 } | |
425 #endif | |
426 | |
427 // Create a device with this external buffer | |
428 pContext->m_pBitmap = new CFX_DIBitmap; | |
429 pContext->m_pBitmap->Create(width, height, FXDIB_Rgb, (uint8_t*)pBuffer); | |
430 pContext->m_pDevice = new CPDF_FxgeDevice; | |
431 ((CPDF_FxgeDevice*)pContext->m_pDevice)->Attach(pContext->m_pBitmap); | |
432 | |
433 #ifdef DEBUG_TRACE | |
434 CPDF_ModuleMgr::Get()->ReportError(999, "Ready for PDF rendering"); | |
435 #endif | |
436 | |
437 // output to bitmap device | |
438 FPDF_RenderPage_Retail(pContext, page, start_x - rect.left, | |
439 start_y - rect.top, size_x, size_y, rotate, flags); | |
440 | |
441 #ifdef DEBUG_TRACE | |
442 CPDF_ModuleMgr::Get()->ReportError(999, "Finished PDF rendering"); | |
443 #endif | |
444 | |
445 // Now output to real device | |
446 HDC hMemDC = CreateCompatibleDC(dc); | |
447 if (hMemDC == NULL) { | |
448 #if defined(DEBUG) || defined(_DEBUG) | |
449 char str[128]; | |
450 memset(str, 0, sizeof(str)); | |
451 FXSYS_snprintf(str, sizeof(str) - 1, "Error CreateCompatibleDC. Error co
de = %d", GetLastError()); | |
452 CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, str); | |
453 #else | |
454 CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, NULL); | |
455 #endif | |
456 } | |
457 | |
458 HGDIOBJ hOldBitmap = SelectObject(hMemDC, pContext->m_hBitmap); | |
459 | |
460 #ifdef DEBUG_TRACE | |
461 CPDF_ModuleMgr::Get()->ReportError(999, "Ready for screen rendering"); | |
462 #endif | |
463 | |
464 BitBlt(dc, rect.left, rect.top, width, height, hMemDC, 0, 0, SRCCOPY); | |
465 SelectObject(hMemDC, hOldBitmap); | |
466 DeleteDC(hMemDC); | |
467 | |
468 #ifdef DEBUG_TRACE | |
469 CPDF_ModuleMgr::Get()->ReportError(999, "Finished screen rendering"); | |
470 #endif | |
471 | |
472 #endif | |
473 if (bBackgroundAlphaNeeded) { | |
474 delete pBitmap; | |
475 pBitmap = NULL; | |
476 } | |
477 delete pContext; | |
478 pPage->RemovePrivateData((void*)1); | |
479 } | |
480 #endif | |
481 | |
482 DLLEXPORT void STDCALL FPDF_RenderPageBitmap(FPDF_BITMAP bitmap, FPDF_PAGE page,
int start_x, int start_y, | |
483 int size_x, int size_y, int rotate, int flags) | |
484 { | |
485 if (bitmap == NULL || page == NULL) return; | |
486 CPDF_Page* pPage = (CPDF_Page*)page; | |
487 | |
488 | |
489 CRenderContext* pContext = new CRenderContext; | |
490 pPage->SetPrivateData((void*)1, pContext, DropContext); | |
491 #ifdef _SKIA_SUPPORT_ | 342 #ifdef _SKIA_SUPPORT_ |
492 pContext->m_pDevice = new CFX_SkiaDevice; | 343 pContext->m_pDevice = new CFX_SkiaDevice; |
493 | 344 ((CFX_SkiaDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)pBitmap); |
494 if (flags & FPDF_REVERSE_BYTE_ORDER) | |
495 ((CFX_SkiaDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)bitmap,0,T
RUE); | |
496 else | |
497 ((CFX_SkiaDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)bitmap); | |
498 #else | 345 #else |
499 pContext->m_pDevice = new CFX_FxgeDevice; | 346 pContext->m_pDevice = new CFX_FxgeDevice; |
500 | 347 ((CFX_FxgeDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)pBitmap); |
501 if (flags & FPDF_REVERSE_BYTE_ORDER) | 348 #endif |
502 ((CFX_FxgeDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)bitmap,0,T
RUE); | 349 } else |
503 else | 350 pContext->m_pDevice = new CFX_WindowsDevice(dc); |
504 ((CFX_FxgeDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)bitmap); | 351 |
505 #endif | 352 FPDF_RenderPage_Retail(pContext, page, start_x, start_y, size_x, size_y, |
506 | 353 rotate, flags, TRUE, NULL); |
507 FPDF_RenderPage_Retail(pContext, page, start_x, start_y, size_x, size_y, | 354 |
508 rotate, flags, TRUE, NULL); | 355 if (bBackgroundAlphaNeeded) { |
509 | 356 if (pBitmap) { |
510 delete pContext; | 357 CFX_WindowsDevice WinDC(dc); |
511 pPage->RemovePrivateData((void*)1); | 358 |
512 } | 359 if (WinDC.GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) { |
513 | 360 CFX_DIBitmap* pDst = new CFX_DIBitmap; |
514 DLLEXPORT void STDCALL FPDF_ClosePage(FPDF_PAGE page) | 361 int pitch = pBitmap->GetPitch(); |
515 { | 362 pDst->Create(size_x, size_y, FXDIB_Rgb32); |
516 if (!page) return; | 363 FXSYS_memset(pDst->GetBuffer(), -1, pitch * size_y); |
517 CPDFSDK_PageView* pPageView = (CPDFSDK_PageView*)(((CPDF_Page*)page))->G
etPrivateData((void*)page); | 364 pDst->CompositeBitmap(0, 0, size_x, size_y, pBitmap, 0, 0, |
518 if (pPageView && pPageView->IsLocked()) { | 365 FXDIB_BLEND_NORMAL, NULL, FALSE, NULL); |
519 pPageView->TakeOverPage(); | 366 WinDC.StretchDIBits(pDst, 0, 0, size_x, size_y); |
520 return; | 367 delete pDst; |
521 } | 368 } else |
522 delete (CPDF_Page*)page; | 369 WinDC.SetDIBits(pBitmap, 0, 0); |
523 | |
524 } | |
525 | |
526 DLLEXPORT void STDCALL FPDF_CloseDocument(FPDF_DOCUMENT document) | |
527 { | |
528 if (!document) | |
529 return; | |
530 CPDF_Document* pDoc = (CPDF_Document*)document; | |
531 CPDF_Parser* pParser = (CPDF_Parser*)pDoc->GetParser(); | |
532 if (pParser == NULL) | |
533 { | |
534 delete pDoc; | |
535 return; | |
536 } | 370 } |
537 delete pParser; | 371 } |
538 } | 372 #else |
539 | 373 // get clip region |
540 DLLEXPORT unsigned long STDCALL FPDF_GetLastError() | 374 RECT rect, cliprect; |
541 { | 375 rect.left = start_x; |
542 return GetLastError(); | 376 rect.top = start_y; |
543 } | 377 rect.right = start_x + size_x; |
544 | 378 rect.bottom = start_y + size_y; |
545 DLLEXPORT void STDCALL FPDF_DeviceToPage(FPDF_PAGE page, int start_x, int start_
y, int size_x, int size_y, | 379 GetClipBox(dc, &cliprect); |
546 int rotate, int device_x, int device_y, double* page_x,
double* page_y) | 380 IntersectRect(&rect, &rect, &cliprect); |
547 { | 381 int width = rect.right - rect.left; |
548 if (page == NULL || page_x == NULL || page_y == NULL) return; | 382 int height = rect.bottom - rect.top; |
549 CPDF_Page* pPage = (CPDF_Page*)page; | 383 |
550 | 384 #ifdef DEBUG_TRACE |
551 CPDF_Matrix page2device; | 385 { |
552 pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotat
e); | 386 char str[128]; |
553 CPDF_Matrix device2page; | 387 memset(str, 0, sizeof(str)); |
554 device2page.SetReverse(page2device); | 388 FXSYS_snprintf(str, sizeof(str) - 1, "Rendering DIB %d x %d", width, |
555 | 389 height); |
556 FX_FLOAT page_x_f, page_y_f; | 390 CPDF_ModuleMgr::Get()->ReportError(999, str); |
557 device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f,
page_y_f); | 391 } |
558 | 392 #endif |
559 *page_x = (page_x_f); | 393 |
560 *page_y = (page_y_f); | 394 // Create a DIB section |
561 } | 395 LPVOID pBuffer; |
562 | 396 BITMAPINFOHEADER bmih; |
563 DLLEXPORT void STDCALL FPDF_PageToDevice(FPDF_PAGE page, int start_x, int start_
y, int size_x, int size_y, | 397 FXSYS_memset(&bmih, 0, sizeof bmih); |
564 int rotate, double page_x, double page_y, int* device_x,
int* device_y) | 398 bmih.biSize = sizeof bmih; |
565 { | 399 bmih.biBitCount = 24; |
566 if (page == NULL || device_x == NULL || device_y == NULL) return; | 400 bmih.biHeight = -height; |
567 CPDF_Page* pPage = (CPDF_Page*)page; | 401 bmih.biPlanes = 1; |
568 | 402 bmih.biWidth = width; |
569 CPDF_Matrix page2device; | 403 pContext->m_hBitmap = CreateDIBSection(dc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, |
570 pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotat
e); | 404 &pBuffer, NULL, 0); |
571 | 405 if (pContext->m_hBitmap == NULL) { |
572 FX_FLOAT device_x_f, device_y_f; | 406 #if defined(DEBUG) || defined(_DEBUG) |
573 page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f, de
vice_y_f); | 407 char str[128]; |
574 | 408 memset(str, 0, sizeof(str)); |
575 *device_x = FXSYS_round(device_x_f); | 409 FXSYS_snprintf(str, sizeof(str) - 1, |
576 *device_y = FXSYS_round(device_y_f); | 410 "Error CreateDIBSection: %d x %d, error code = %d", width, |
577 } | 411 height, GetLastError()); |
578 | 412 CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, str); |
579 DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_Create(int width, int height, int alpha
) | 413 #else |
580 { | 414 CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, NULL); |
581 nonstd::unique_ptr<CFX_DIBitmap> pBitmap(new CFX_DIBitmap); | 415 #endif |
582 if (!pBitmap->Create(width, height, alpha ? FXDIB_Argb : FXDIB_Rgb32)) { | 416 } |
583 return NULL; | 417 FXSYS_memset(pBuffer, 0xff, height * ((width * 3 + 3) / 4 * 4)); |
| 418 |
| 419 #ifdef DEBUG_TRACE |
| 420 { CPDF_ModuleMgr::Get()->ReportError(999, "DIBSection created"); } |
| 421 #endif |
| 422 |
| 423 // Create a device with this external buffer |
| 424 pContext->m_pBitmap = new CFX_DIBitmap; |
| 425 pContext->m_pBitmap->Create(width, height, FXDIB_Rgb, (uint8_t*)pBuffer); |
| 426 pContext->m_pDevice = new CPDF_FxgeDevice; |
| 427 ((CPDF_FxgeDevice*)pContext->m_pDevice)->Attach(pContext->m_pBitmap); |
| 428 |
| 429 #ifdef DEBUG_TRACE |
| 430 CPDF_ModuleMgr::Get()->ReportError(999, "Ready for PDF rendering"); |
| 431 #endif |
| 432 |
| 433 // output to bitmap device |
| 434 FPDF_RenderPage_Retail(pContext, page, start_x - rect.left, |
| 435 start_y - rect.top, size_x, size_y, rotate, flags); |
| 436 |
| 437 #ifdef DEBUG_TRACE |
| 438 CPDF_ModuleMgr::Get()->ReportError(999, "Finished PDF rendering"); |
| 439 #endif |
| 440 |
| 441 // Now output to real device |
| 442 HDC hMemDC = CreateCompatibleDC(dc); |
| 443 if (hMemDC == NULL) { |
| 444 #if defined(DEBUG) || defined(_DEBUG) |
| 445 char str[128]; |
| 446 memset(str, 0, sizeof(str)); |
| 447 FXSYS_snprintf(str, sizeof(str) - 1, |
| 448 "Error CreateCompatibleDC. Error code = %d", GetLastError()); |
| 449 CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, str); |
| 450 #else |
| 451 CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, NULL); |
| 452 #endif |
| 453 } |
| 454 |
| 455 HGDIOBJ hOldBitmap = SelectObject(hMemDC, pContext->m_hBitmap); |
| 456 |
| 457 #ifdef DEBUG_TRACE |
| 458 CPDF_ModuleMgr::Get()->ReportError(999, "Ready for screen rendering"); |
| 459 #endif |
| 460 |
| 461 BitBlt(dc, rect.left, rect.top, width, height, hMemDC, 0, 0, SRCCOPY); |
| 462 SelectObject(hMemDC, hOldBitmap); |
| 463 DeleteDC(hMemDC); |
| 464 |
| 465 #ifdef DEBUG_TRACE |
| 466 CPDF_ModuleMgr::Get()->ReportError(999, "Finished screen rendering"); |
| 467 #endif |
| 468 |
| 469 #endif |
| 470 if (bBackgroundAlphaNeeded) { |
| 471 delete pBitmap; |
| 472 pBitmap = NULL; |
| 473 } |
| 474 delete pContext; |
| 475 pPage->RemovePrivateData((void*)1); |
| 476 } |
| 477 #endif |
| 478 |
| 479 DLLEXPORT void STDCALL FPDF_RenderPageBitmap(FPDF_BITMAP bitmap, |
| 480 FPDF_PAGE page, |
| 481 int start_x, |
| 482 int start_y, |
| 483 int size_x, |
| 484 int size_y, |
| 485 int rotate, |
| 486 int flags) { |
| 487 if (bitmap == NULL || page == NULL) |
| 488 return; |
| 489 CPDF_Page* pPage = (CPDF_Page*)page; |
| 490 |
| 491 CRenderContext* pContext = new CRenderContext; |
| 492 pPage->SetPrivateData((void*)1, pContext, DropContext); |
| 493 #ifdef _SKIA_SUPPORT_ |
| 494 pContext->m_pDevice = new CFX_SkiaDevice; |
| 495 |
| 496 if (flags & FPDF_REVERSE_BYTE_ORDER) |
| 497 ((CFX_SkiaDevice*)pContext->m_pDevice) |
| 498 ->Attach((CFX_DIBitmap*)bitmap, 0, TRUE); |
| 499 else |
| 500 ((CFX_SkiaDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)bitmap); |
| 501 #else |
| 502 pContext->m_pDevice = new CFX_FxgeDevice; |
| 503 |
| 504 if (flags & FPDF_REVERSE_BYTE_ORDER) |
| 505 ((CFX_FxgeDevice*)pContext->m_pDevice) |
| 506 ->Attach((CFX_DIBitmap*)bitmap, 0, TRUE); |
| 507 else |
| 508 ((CFX_FxgeDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)bitmap); |
| 509 #endif |
| 510 |
| 511 FPDF_RenderPage_Retail(pContext, page, start_x, start_y, size_x, size_y, |
| 512 rotate, flags, TRUE, NULL); |
| 513 |
| 514 delete pContext; |
| 515 pPage->RemovePrivateData((void*)1); |
| 516 } |
| 517 |
| 518 DLLEXPORT void STDCALL FPDF_ClosePage(FPDF_PAGE page) { |
| 519 if (!page) |
| 520 return; |
| 521 CPDFSDK_PageView* pPageView = |
| 522 (CPDFSDK_PageView*)(((CPDF_Page*)page))->GetPrivateData((void*)page); |
| 523 if (pPageView && pPageView->IsLocked()) { |
| 524 pPageView->TakeOverPage(); |
| 525 return; |
| 526 } |
| 527 delete (CPDF_Page*)page; |
| 528 } |
| 529 |
| 530 DLLEXPORT void STDCALL FPDF_CloseDocument(FPDF_DOCUMENT document) { |
| 531 if (!document) |
| 532 return; |
| 533 CPDF_Document* pDoc = (CPDF_Document*)document; |
| 534 CPDF_Parser* pParser = (CPDF_Parser*)pDoc->GetParser(); |
| 535 if (pParser == NULL) { |
| 536 delete pDoc; |
| 537 return; |
| 538 } |
| 539 delete pParser; |
| 540 } |
| 541 |
| 542 DLLEXPORT unsigned long STDCALL FPDF_GetLastError() { |
| 543 return GetLastError(); |
| 544 } |
| 545 |
| 546 DLLEXPORT void STDCALL FPDF_DeviceToPage(FPDF_PAGE page, |
| 547 int start_x, |
| 548 int start_y, |
| 549 int size_x, |
| 550 int size_y, |
| 551 int rotate, |
| 552 int device_x, |
| 553 int device_y, |
| 554 double* page_x, |
| 555 double* page_y) { |
| 556 if (page == NULL || page_x == NULL || page_y == NULL) |
| 557 return; |
| 558 CPDF_Page* pPage = (CPDF_Page*)page; |
| 559 |
| 560 CPDF_Matrix page2device; |
| 561 pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, |
| 562 rotate); |
| 563 CPDF_Matrix device2page; |
| 564 device2page.SetReverse(page2device); |
| 565 |
| 566 FX_FLOAT page_x_f, page_y_f; |
| 567 device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f, |
| 568 page_y_f); |
| 569 |
| 570 *page_x = (page_x_f); |
| 571 *page_y = (page_y_f); |
| 572 } |
| 573 |
| 574 DLLEXPORT void STDCALL FPDF_PageToDevice(FPDF_PAGE page, |
| 575 int start_x, |
| 576 int start_y, |
| 577 int size_x, |
| 578 int size_y, |
| 579 int rotate, |
| 580 double page_x, |
| 581 double page_y, |
| 582 int* device_x, |
| 583 int* device_y) { |
| 584 if (page == NULL || device_x == NULL || device_y == NULL) |
| 585 return; |
| 586 CPDF_Page* pPage = (CPDF_Page*)page; |
| 587 |
| 588 CPDF_Matrix page2device; |
| 589 pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, |
| 590 rotate); |
| 591 |
| 592 FX_FLOAT device_x_f, device_y_f; |
| 593 page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f, |
| 594 device_y_f); |
| 595 |
| 596 *device_x = FXSYS_round(device_x_f); |
| 597 *device_y = FXSYS_round(device_y_f); |
| 598 } |
| 599 |
| 600 DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_Create(int width, |
| 601 int height, |
| 602 int alpha) { |
| 603 nonstd::unique_ptr<CFX_DIBitmap> pBitmap(new CFX_DIBitmap); |
| 604 if (!pBitmap->Create(width, height, alpha ? FXDIB_Argb : FXDIB_Rgb32)) { |
| 605 return NULL; |
| 606 } |
| 607 return pBitmap.release(); |
| 608 } |
| 609 |
| 610 DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_CreateEx(int width, |
| 611 int height, |
| 612 int format, |
| 613 void* first_scan, |
| 614 int stride) { |
| 615 FXDIB_Format fx_format; |
| 616 switch (format) { |
| 617 case FPDFBitmap_Gray: |
| 618 fx_format = FXDIB_8bppRgb; |
| 619 break; |
| 620 case FPDFBitmap_BGR: |
| 621 fx_format = FXDIB_Rgb; |
| 622 break; |
| 623 case FPDFBitmap_BGRx: |
| 624 fx_format = FXDIB_Rgb32; |
| 625 break; |
| 626 case FPDFBitmap_BGRA: |
| 627 fx_format = FXDIB_Argb; |
| 628 break; |
| 629 default: |
| 630 return NULL; |
| 631 } |
| 632 CFX_DIBitmap* pBitmap = new CFX_DIBitmap; |
| 633 pBitmap->Create(width, height, fx_format, (uint8_t*)first_scan, stride); |
| 634 return pBitmap; |
| 635 } |
| 636 |
| 637 DLLEXPORT void STDCALL FPDFBitmap_FillRect(FPDF_BITMAP bitmap, |
| 638 int left, |
| 639 int top, |
| 640 int width, |
| 641 int height, |
| 642 FPDF_DWORD color) { |
| 643 if (bitmap == NULL) |
| 644 return; |
| 645 #ifdef _SKIA_SUPPORT_ |
| 646 CFX_SkiaDevice device; |
| 647 #else |
| 648 CFX_FxgeDevice device; |
| 649 #endif |
| 650 device.Attach((CFX_DIBitmap*)bitmap); |
| 651 if (!((CFX_DIBitmap*)bitmap)->HasAlpha()) |
| 652 color |= 0xFF000000; |
| 653 FX_RECT rect(left, top, left + width, top + height); |
| 654 device.FillRect(&rect, color); |
| 655 } |
| 656 |
| 657 DLLEXPORT void* STDCALL FPDFBitmap_GetBuffer(FPDF_BITMAP bitmap) { |
| 658 if (bitmap == NULL) |
| 659 return NULL; |
| 660 return ((CFX_DIBitmap*)bitmap)->GetBuffer(); |
| 661 } |
| 662 |
| 663 DLLEXPORT int STDCALL FPDFBitmap_GetWidth(FPDF_BITMAP bitmap) { |
| 664 if (bitmap == NULL) |
| 665 return 0; |
| 666 return ((CFX_DIBitmap*)bitmap)->GetWidth(); |
| 667 } |
| 668 |
| 669 DLLEXPORT int STDCALL FPDFBitmap_GetHeight(FPDF_BITMAP bitmap) { |
| 670 if (bitmap == NULL) |
| 671 return 0; |
| 672 return ((CFX_DIBitmap*)bitmap)->GetHeight(); |
| 673 } |
| 674 |
| 675 DLLEXPORT int STDCALL FPDFBitmap_GetStride(FPDF_BITMAP bitmap) { |
| 676 if (bitmap == NULL) |
| 677 return 0; |
| 678 return ((CFX_DIBitmap*)bitmap)->GetPitch(); |
| 679 } |
| 680 |
| 681 DLLEXPORT void STDCALL FPDFBitmap_Destroy(FPDF_BITMAP bitmap) { |
| 682 delete (CFX_DIBitmap*)bitmap; |
| 683 } |
| 684 |
| 685 void FPDF_RenderPage_Retail(CRenderContext* pContext, |
| 686 FPDF_PAGE page, |
| 687 int start_x, |
| 688 int start_y, |
| 689 int size_x, |
| 690 int size_y, |
| 691 int rotate, |
| 692 int flags, |
| 693 FX_BOOL bNeedToRestore, |
| 694 IFSDK_PAUSE_Adapter* pause) { |
| 695 CPDF_Page* pPage = (CPDF_Page*)page; |
| 696 if (pPage == NULL) |
| 697 return; |
| 698 |
| 699 if (!pContext->m_pOptions) |
| 700 pContext->m_pOptions = new CPDF_RenderOptions; |
| 701 |
| 702 if (flags & FPDF_LCD_TEXT) |
| 703 pContext->m_pOptions->m_Flags |= RENDER_CLEARTYPE; |
| 704 else |
| 705 pContext->m_pOptions->m_Flags &= ~RENDER_CLEARTYPE; |
| 706 if (flags & FPDF_NO_NATIVETEXT) |
| 707 pContext->m_pOptions->m_Flags |= RENDER_NO_NATIVETEXT; |
| 708 if (flags & FPDF_RENDER_LIMITEDIMAGECACHE) |
| 709 pContext->m_pOptions->m_Flags |= RENDER_LIMITEDIMAGECACHE; |
| 710 if (flags & FPDF_RENDER_FORCEHALFTONE) |
| 711 pContext->m_pOptions->m_Flags |= RENDER_FORCE_HALFTONE; |
| 712 if (flags & FPDF_RENDER_NO_SMOOTHTEXT) |
| 713 pContext->m_pOptions->m_Flags |= RENDER_NOTEXTSMOOTH; |
| 714 if (flags & FPDF_RENDER_NO_SMOOTHIMAGE) |
| 715 pContext->m_pOptions->m_Flags |= RENDER_NOIMAGESMOOTH; |
| 716 if (flags & FPDF_RENDER_NO_SMOOTHPATH) |
| 717 pContext->m_pOptions->m_Flags |= RENDER_NOPATHSMOOTH; |
| 718 // Grayscale output |
| 719 if (flags & FPDF_GRAYSCALE) { |
| 720 pContext->m_pOptions->m_ColorMode = RENDER_COLOR_GRAY; |
| 721 pContext->m_pOptions->m_ForeColor = 0; |
| 722 pContext->m_pOptions->m_BackColor = 0xffffff; |
| 723 } |
| 724 const CPDF_OCContext::UsageType usage = |
| 725 (flags & FPDF_PRINTING) ? CPDF_OCContext::Print : CPDF_OCContext::View; |
| 726 pContext->m_pOptions->m_AddFlags = flags >> 8; |
| 727 pContext->m_pOptions->m_pOCContext = |
| 728 new CPDF_OCContext(pPage->m_pDocument, usage); |
| 729 |
| 730 CFX_AffineMatrix matrix; |
| 731 pPage->GetDisplayMatrix(matrix, start_x, start_y, size_x, size_y, rotate); |
| 732 |
| 733 FX_RECT clip; |
| 734 clip.left = start_x; |
| 735 clip.right = start_x + size_x; |
| 736 clip.top = start_y; |
| 737 clip.bottom = start_y + size_y; |
| 738 pContext->m_pDevice->SaveState(); |
| 739 pContext->m_pDevice->SetClip_Rect(&clip); |
| 740 |
| 741 pContext->m_pContext = new CPDF_RenderContext; |
| 742 pContext->m_pContext->Create(pPage); |
| 743 pContext->m_pContext->AppendObjectList(pPage, &matrix); |
| 744 |
| 745 if (flags & FPDF_ANNOT) { |
| 746 pContext->m_pAnnots = new CPDF_AnnotList(pPage); |
| 747 FX_BOOL bPrinting = pContext->m_pDevice->GetDeviceClass() != FXDC_DISPLAY; |
| 748 pContext->m_pAnnots->DisplayAnnots(pPage, pContext->m_pContext, bPrinting, |
| 749 &matrix, TRUE, NULL); |
| 750 } |
| 751 |
| 752 pContext->m_pRenderer = new CPDF_ProgressiveRenderer( |
| 753 pContext->m_pContext, pContext->m_pDevice, pContext->m_pOptions); |
| 754 pContext->m_pRenderer->Start(pause); |
| 755 if (bNeedToRestore) |
| 756 pContext->m_pDevice->RestoreState(); |
| 757 } |
| 758 |
| 759 DLLEXPORT int STDCALL FPDF_GetPageSizeByIndex(FPDF_DOCUMENT document, |
| 760 int page_index, |
| 761 double* width, |
| 762 double* height) { |
| 763 CPDF_Document* pDoc = (CPDF_Document*)document; |
| 764 if (pDoc == NULL) |
| 765 return FALSE; |
| 766 |
| 767 CPDF_Dictionary* pDict = pDoc->GetPage(page_index); |
| 768 if (pDict == NULL) |
| 769 return FALSE; |
| 770 |
| 771 CPDF_Page page; |
| 772 page.Load(pDoc, pDict); |
| 773 *width = page.GetPageWidth(); |
| 774 *height = page.GetPageHeight(); |
| 775 |
| 776 return TRUE; |
| 777 } |
| 778 |
| 779 DLLEXPORT FPDF_BOOL STDCALL |
| 780 FPDF_VIEWERREF_GetPrintScaling(FPDF_DOCUMENT document) { |
| 781 CPDF_Document* pDoc = (CPDF_Document*)document; |
| 782 if (!pDoc) |
| 783 return TRUE; |
| 784 CPDF_ViewerPreferences viewRef(pDoc); |
| 785 return viewRef.PrintScaling(); |
| 786 } |
| 787 |
| 788 DLLEXPORT int STDCALL FPDF_VIEWERREF_GetNumCopies(FPDF_DOCUMENT document) { |
| 789 CPDF_Document* pDoc = (CPDF_Document*)document; |
| 790 if (!pDoc) |
| 791 return 1; |
| 792 CPDF_ViewerPreferences viewRef(pDoc); |
| 793 return viewRef.NumCopies(); |
| 794 } |
| 795 |
| 796 DLLEXPORT FPDF_PAGERANGE STDCALL |
| 797 FPDF_VIEWERREF_GetPrintPageRange(FPDF_DOCUMENT document) { |
| 798 CPDF_Document* pDoc = (CPDF_Document*)document; |
| 799 if (!pDoc) |
| 800 return NULL; |
| 801 CPDF_ViewerPreferences viewRef(pDoc); |
| 802 return viewRef.PrintPageRange(); |
| 803 } |
| 804 |
| 805 DLLEXPORT FPDF_DUPLEXTYPE STDCALL |
| 806 FPDF_VIEWERREF_GetDuplex(FPDF_DOCUMENT document) { |
| 807 CPDF_Document* pDoc = (CPDF_Document*)document; |
| 808 if (!pDoc) |
| 809 return DuplexUndefined; |
| 810 CPDF_ViewerPreferences viewRef(pDoc); |
| 811 CFX_ByteString duplex = viewRef.Duplex(); |
| 812 if (FX_BSTRC("Simplex") == duplex) |
| 813 return Simplex; |
| 814 if (FX_BSTRC("DuplexFlipShortEdge") == duplex) |
| 815 return DuplexFlipShortEdge; |
| 816 if (FX_BSTRC("DuplexFlipLongEdge") == duplex) |
| 817 return DuplexFlipLongEdge; |
| 818 return DuplexUndefined; |
| 819 } |
| 820 |
| 821 DLLEXPORT FPDF_DWORD STDCALL FPDF_CountNamedDests(FPDF_DOCUMENT document) { |
| 822 if (!document) |
| 823 return 0; |
| 824 CPDF_Document* pDoc = (CPDF_Document*)document; |
| 825 |
| 826 CPDF_Dictionary* pRoot = pDoc->GetRoot(); |
| 827 if (!pRoot) |
| 828 return 0; |
| 829 |
| 830 CPDF_NameTree nameTree(pDoc, FX_BSTRC("Dests")); |
| 831 int count = nameTree.GetCount(); |
| 832 CPDF_Dictionary* pDest = pRoot->GetDict(FX_BSTRC("Dests")); |
| 833 if (pDest) |
| 834 count += pDest->GetCount(); |
| 835 return count; |
| 836 } |
| 837 |
| 838 DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDestByName(FPDF_DOCUMENT document, |
| 839 FPDF_BYTESTRING name) { |
| 840 if (!document) |
| 841 return NULL; |
| 842 if (!name || name[0] == 0) |
| 843 return NULL; |
| 844 |
| 845 CPDF_Document* pDoc = (CPDF_Document*)document; |
| 846 CPDF_NameTree name_tree(pDoc, FX_BSTRC("Dests")); |
| 847 return name_tree.LookupNamedDest(pDoc, name); |
| 848 } |
| 849 |
| 850 DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDest(FPDF_DOCUMENT document, |
| 851 int index, |
| 852 void* buffer, |
| 853 long* buflen) { |
| 854 if (!buffer) |
| 855 *buflen = 0; |
| 856 if (!document || index < 0) |
| 857 return NULL; |
| 858 CPDF_Document* pDoc = (CPDF_Document*)document; |
| 859 |
| 860 CPDF_Dictionary* pRoot = pDoc->GetRoot(); |
| 861 if (!pRoot) |
| 862 return NULL; |
| 863 |
| 864 CPDF_Object* pDestObj = NULL; |
| 865 CFX_ByteString bsName; |
| 866 CPDF_NameTree nameTree(pDoc, FX_BSTRC("Dests")); |
| 867 int count = nameTree.GetCount(); |
| 868 if (index >= count) { |
| 869 CPDF_Dictionary* pDest = pRoot->GetDict(FX_BSTRC("Dests")); |
| 870 if (!pDest) |
| 871 return NULL; |
| 872 if (index >= count + pDest->GetCount()) |
| 873 return NULL; |
| 874 index -= count; |
| 875 FX_POSITION pos = pDest->GetStartPos(); |
| 876 int i = 0; |
| 877 while (pos) { |
| 878 pDestObj = pDest->GetNextElement(pos, bsName); |
| 879 if (!pDestObj) |
| 880 continue; |
| 881 if (i == index) |
| 882 break; |
| 883 i++; |
584 } | 884 } |
585 return pBitmap.release(); | 885 } else { |
586 } | 886 pDestObj = nameTree.LookupValue(index, bsName); |
587 | 887 } |
588 DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_CreateEx(int width, int height, int for
mat, void* first_scan, int stride) | 888 if (!pDestObj) |
589 { | 889 return NULL; |
590 FXDIB_Format fx_format; | 890 if (pDestObj->GetType() == PDFOBJ_DICTIONARY) { |
591 switch (format) { | 891 pDestObj = ((CPDF_Dictionary*)pDestObj)->GetArray(FX_BSTRC("D")); |
592 case FPDFBitmap_Gray: | 892 if (!pDestObj) |
593 fx_format = FXDIB_8bppRgb; | 893 return NULL; |
594 break; | 894 } |
595 case FPDFBitmap_BGR: | 895 if (pDestObj->GetType() != PDFOBJ_ARRAY) |
596 fx_format = FXDIB_Rgb; | 896 return NULL; |
597 break; | 897 CFX_WideString wsName = PDF_DecodeText(bsName); |
598 case FPDFBitmap_BGRx: | 898 CFX_ByteString utf16Name = wsName.UTF16LE_Encode(); |
599 fx_format = FXDIB_Rgb32; | 899 unsigned int len = utf16Name.GetLength(); |
600 break; | 900 if (!buffer) { |
601 case FPDFBitmap_BGRA: | 901 *buflen = len; |
602 fx_format = FXDIB_Argb; | 902 } else if (*buflen >= len) { |
603 break; | 903 memcpy(buffer, utf16Name.c_str(), len); |
604 default: | 904 *buflen = len; |
605 return NULL; | 905 } else { |
606 } | 906 *buflen = -1; |
607 CFX_DIBitmap* pBitmap = new CFX_DIBitmap; | 907 } |
608 pBitmap->Create(width, height, fx_format, (uint8_t*)first_scan, stride); | 908 return (FPDF_DEST)pDestObj; |
609 return pBitmap; | 909 } |
610 } | |
611 | |
612 DLLEXPORT void STDCALL FPDFBitmap_FillRect(FPDF_BITMAP bitmap, int left, int top
, int width, int height, FPDF_DWORD color) | |
613 { | |
614 if (bitmap == NULL) return; | |
615 #ifdef _SKIA_SUPPORT_ | |
616 CFX_SkiaDevice device; | |
617 #else | |
618 CFX_FxgeDevice device; | |
619 #endif | |
620 device.Attach((CFX_DIBitmap*)bitmap); | |
621 if (!((CFX_DIBitmap*)bitmap)->HasAlpha()) color |= 0xFF000000; | |
622 FX_RECT rect(left, top, left+width, top+height); | |
623 device.FillRect(&rect, color); | |
624 } | |
625 | |
626 DLLEXPORT void* STDCALL FPDFBitmap_GetBuffer(FPDF_BITMAP bitmap) | |
627 { | |
628 if (bitmap == NULL) return NULL; | |
629 return ((CFX_DIBitmap*)bitmap)->GetBuffer(); | |
630 } | |
631 | |
632 DLLEXPORT int STDCALL FPDFBitmap_GetWidth(FPDF_BITMAP bitmap) | |
633 { | |
634 if (bitmap == NULL) return 0; | |
635 return ((CFX_DIBitmap*)bitmap)->GetWidth(); | |
636 } | |
637 | |
638 DLLEXPORT int STDCALL FPDFBitmap_GetHeight(FPDF_BITMAP bitmap) | |
639 { | |
640 if (bitmap == NULL) return 0; | |
641 return ((CFX_DIBitmap*)bitmap)->GetHeight(); | |
642 } | |
643 | |
644 DLLEXPORT int STDCALL FPDFBitmap_GetStride(FPDF_BITMAP bitmap) | |
645 { | |
646 if (bitmap == NULL) return 0; | |
647 return ((CFX_DIBitmap*)bitmap)->GetPitch(); | |
648 } | |
649 | |
650 DLLEXPORT void STDCALL FPDFBitmap_Destroy(FPDF_BITMAP bitmap) | |
651 { | |
652 delete (CFX_DIBitmap*)bitmap; | |
653 } | |
654 | |
655 void FPDF_RenderPage_Retail(CRenderContext* pContext, FPDF_PAGE page, int start_
x, int start_y, int size_x, int size_y, | |
656 int rotate, int flags,FX_BOOL bNeedToRestore, IFSDK_
PAUSE_Adapter * pause ) | |
657 { | |
658 CPDF_Page* pPage = (CPDF_Page*)page; | |
659 if (pPage == NULL) return; | |
660 | |
661 if (!pContext->m_pOptions) | |
662 pContext->m_pOptions = new CPDF_RenderOptions; | |
663 | |
664 if (flags & FPDF_LCD_TEXT) | |
665 pContext->m_pOptions->m_Flags |= RENDER_CLEARTYPE; | |
666 else | |
667 pContext->m_pOptions->m_Flags &= ~RENDER_CLEARTYPE; | |
668 if (flags & FPDF_NO_NATIVETEXT) | |
669 pContext->m_pOptions->m_Flags |= RENDER_NO_NATIVETEXT; | |
670 if (flags & FPDF_RENDER_LIMITEDIMAGECACHE) | |
671 pContext->m_pOptions->m_Flags |= RENDER_LIMITEDIMAGECACHE; | |
672 if (flags & FPDF_RENDER_FORCEHALFTONE) | |
673 pContext->m_pOptions->m_Flags |= RENDER_FORCE_HALFTONE; | |
674 if (flags & FPDF_RENDER_NO_SMOOTHTEXT) | |
675 pContext->m_pOptions->m_Flags |= RENDER_NOTEXTSMOOTH; | |
676 if (flags & FPDF_RENDER_NO_SMOOTHIMAGE) | |
677 pContext->m_pOptions->m_Flags |= RENDER_NOIMAGESMOOTH; | |
678 if (flags & FPDF_RENDER_NO_SMOOTHPATH) | |
679 pContext->m_pOptions->m_Flags |= RENDER_NOPATHSMOOTH; | |
680 //Grayscale output | |
681 if (flags & FPDF_GRAYSCALE) | |
682 { | |
683 pContext->m_pOptions->m_ColorMode = RENDER_COLOR_GRAY; | |
684 pContext->m_pOptions->m_ForeColor = 0; | |
685 pContext->m_pOptions->m_BackColor = 0xffffff; | |
686 } | |
687 const CPDF_OCContext::UsageType usage = (flags & FPDF_PRINTING) ? CPDF_OCCon
text::Print : CPDF_OCContext::View; | |
688 pContext->m_pOptions->m_AddFlags = flags >> 8; | |
689 pContext->m_pOptions->m_pOCContext = new CPDF_OCContext(pPage->m_pDocument,
usage); | |
690 | |
691 CFX_AffineMatrix matrix; | |
692 pPage->GetDisplayMatrix(matrix, start_x, start_y, size_x, size_y, rotate); | |
693 | |
694 FX_RECT clip; | |
695 clip.left = start_x; | |
696 clip.right = start_x + size_x; | |
697 clip.top = start_y; | |
698 clip.bottom = start_y + size_y; | |
699 pContext->m_pDevice->SaveState(); | |
700 pContext->m_pDevice->SetClip_Rect(&clip); | |
701 | |
702 pContext->m_pContext = new CPDF_RenderContext; | |
703 pContext->m_pContext->Create(pPage); | |
704 pContext->m_pContext->AppendObjectList(pPage, &matrix); | |
705 | |
706 if (flags & FPDF_ANNOT) { | |
707 pContext->m_pAnnots = new CPDF_AnnotList(pPage); | |
708 FX_BOOL bPrinting = pContext->m_pDevice->GetDeviceClass() != FXDC_DISPLA
Y; | |
709 pContext->m_pAnnots->DisplayAnnots(pPage, pContext->m_pContext, bPrintin
g, &matrix, TRUE, NULL); | |
710 } | |
711 | |
712 pContext->m_pRenderer = new CPDF_ProgressiveRenderer( | |
713 pContext->m_pContext, pContext->m_pDevice, pContext->m_pOptions); | |
714 pContext->m_pRenderer->Start(pause); | |
715 if (bNeedToRestore) | |
716 pContext->m_pDevice->RestoreState(); | |
717 } | |
718 | |
719 DLLEXPORT int STDCALL FPDF_GetPageSizeByIndex(FPDF_DOCUMENT document, int page_i
ndex, double* width, double* height) | |
720 { | |
721 CPDF_Document* pDoc = (CPDF_Document*)document; | |
722 if(pDoc == NULL) | |
723 return FALSE; | |
724 | |
725 CPDF_Dictionary* pDict = pDoc->GetPage(page_index); | |
726 if (pDict == NULL) return FALSE; | |
727 | |
728 CPDF_Page page; | |
729 page.Load(pDoc, pDict); | |
730 *width = page.GetPageWidth(); | |
731 *height = page.GetPageHeight(); | |
732 | |
733 return TRUE; | |
734 } | |
735 | |
736 DLLEXPORT FPDF_BOOL STDCALL FPDF_VIEWERREF_GetPrintScaling(FPDF_DOCUMENT documen
t) | |
737 { | |
738 CPDF_Document* pDoc = (CPDF_Document*)document; | |
739 if (!pDoc) return TRUE; | |
740 CPDF_ViewerPreferences viewRef(pDoc); | |
741 return viewRef.PrintScaling(); | |
742 } | |
743 | |
744 DLLEXPORT int STDCALL FPDF_VIEWERREF_GetNumCopies(FPDF_DOCUMENT document) | |
745 { | |
746 CPDF_Document* pDoc = (CPDF_Document*)document; | |
747 if (!pDoc) return 1; | |
748 CPDF_ViewerPreferences viewRef(pDoc); | |
749 return viewRef.NumCopies(); | |
750 } | |
751 | |
752 DLLEXPORT FPDF_PAGERANGE STDCALL FPDF_VIEWERREF_GetPrintPageRange(FPDF_DOCUMENT
document) | |
753 { | |
754 CPDF_Document* pDoc = (CPDF_Document*)document; | |
755 if (!pDoc) return NULL; | |
756 CPDF_ViewerPreferences viewRef(pDoc); | |
757 return viewRef.PrintPageRange(); | |
758 } | |
759 | |
760 DLLEXPORT FPDF_DUPLEXTYPE STDCALL FPDF_VIEWERREF_GetDuplex(FPDF_DOCUMENT documen
t) | |
761 { | |
762 CPDF_Document* pDoc = (CPDF_Document*)document; | |
763 if (!pDoc) return DuplexUndefined; | |
764 CPDF_ViewerPreferences viewRef(pDoc); | |
765 CFX_ByteString duplex = viewRef.Duplex(); | |
766 if (FX_BSTRC("Simplex") == duplex) | |
767 return Simplex; | |
768 if (FX_BSTRC("DuplexFlipShortEdge") == duplex) | |
769 return DuplexFlipShortEdge; | |
770 if (FX_BSTRC("DuplexFlipLongEdge") == duplex) | |
771 return DuplexFlipLongEdge; | |
772 return DuplexUndefined; | |
773 } | |
774 | |
775 DLLEXPORT FPDF_DWORD STDCALL FPDF_CountNamedDests(FPDF_DOCUMENT document) | |
776 { | |
777 if (!document) return 0; | |
778 CPDF_Document* pDoc = (CPDF_Document*)document; | |
779 | |
780 CPDF_Dictionary* pRoot = pDoc->GetRoot(); | |
781 if (!pRoot) return 0; | |
782 | |
783 CPDF_NameTree nameTree(pDoc, FX_BSTRC("Dests")); | |
784 int count = nameTree.GetCount(); | |
785 CPDF_Dictionary* pDest = pRoot->GetDict(FX_BSTRC("Dests")); | |
786 if (pDest) | |
787 count += pDest->GetCount(); | |
788 return count; | |
789 } | |
790 | |
791 DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDestByName(FPDF_DOCUMENT document,FPDF_
BYTESTRING name) | |
792 { | |
793 if (!document) | |
794 return NULL; | |
795 if (!name || name[0] == 0) | |
796 return NULL; | |
797 | |
798 CPDF_Document* pDoc = (CPDF_Document*)document; | |
799 CPDF_NameTree name_tree(pDoc, FX_BSTRC("Dests")); | |
800 return name_tree.LookupNamedDest(pDoc, name); | |
801 } | |
802 | |
803 DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDest(FPDF_DOCUMENT document, int index,
void* buffer, long* buflen) | |
804 { | |
805 if (!buffer) | |
806 *buflen = 0; | |
807 if (!document || index < 0) return NULL; | |
808 CPDF_Document* pDoc = (CPDF_Document*)document; | |
809 | |
810 CPDF_Dictionary* pRoot = pDoc->GetRoot(); | |
811 if (!pRoot) return NULL; | |
812 | |
813 CPDF_Object* pDestObj = NULL; | |
814 CFX_ByteString bsName; | |
815 CPDF_NameTree nameTree(pDoc, FX_BSTRC("Dests")); | |
816 int count = nameTree.GetCount(); | |
817 if (index >= count) { | |
818 CPDF_Dictionary* pDest = pRoot->GetDict(FX_BSTRC("Dests")); | |
819 if (!pDest) return NULL; | |
820 if (index >= count + pDest->GetCount()) return NULL; | |
821 index -= count; | |
822 FX_POSITION pos = pDest->GetStartPos(); | |
823 int i = 0; | |
824 while (pos) { | |
825 pDestObj = pDest->GetNextElement(pos, bsName); | |
826 if (!pDestObj) continue; | |
827 if (i == index) break; | |
828 i++; | |
829 } | |
830 } else { | |
831 pDestObj = nameTree.LookupValue(index, bsName); | |
832 } | |
833 if (!pDestObj) return NULL; | |
834 if (pDestObj->GetType() == PDFOBJ_DICTIONARY) { | |
835 pDestObj = ((CPDF_Dictionary*)pDestObj)->GetArray(FX_BSTRC("D")); | |
836 if (!pDestObj) return NULL; | |
837 } | |
838 if (pDestObj->GetType() != PDFOBJ_ARRAY) return NULL; | |
839 CFX_WideString wsName = PDF_DecodeText(bsName); | |
840 CFX_ByteString utf16Name = wsName.UTF16LE_Encode(); | |
841 unsigned int len = utf16Name.GetLength(); | |
842 if (!buffer) { | |
843 *buflen = len; | |
844 } else if (*buflen >= len) { | |
845 memcpy(buffer, utf16Name.c_str(), len); | |
846 *buflen = len; | |
847 } else { | |
848 *buflen = -1; | |
849 } | |
850 return (FPDF_DEST)pDestObj; | |
851 } | |
OLD | NEW |