| 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 |