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