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.
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
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 #include "../../third_party/numerics/safe_conversions_impl.h"
14 CPDF_CustomAccess::CPDF_CustomAccess(FPDF_FILEACCESS* pFileAccess)
16 m_FileAccess = *pFileAccess;
17 m_BufferOffset = (FX_DWORD)-1;
20 FX_BOOL CPDF_CustomAccess::GetByte(FX_DWORD pos, FX_BYTE& ch)
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
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))
32 ch = m_Buffer[pos - m_BufferOffset];
36 FX_BOOL CPDF_CustomAccess::GetBlock(FX_DWORD pos, FX_LPBYTE pBuf, FX_DWORD size)
38 FX_SAFE_DWORD newPos = size;
40 if (!newPos.IsValid() || newPos.ValueOrDie() > m_FileAccess.m_FileLen) {
43 return m_FileAccess.m_GetBlock(m_FileAccess.m_Param, pos, pBuf, size);
46 FX_BOOL CPDF_CustomAccess::ReadBlock(void* buffer, FX_FILESIZE offset, size_t size)
51 FX_SAFE_FILESIZE newPos = base::checked_cast<FX_FILESIZE, size_t>(size);
53 if (!newPos.IsValid() || newPos.ValueOrDie() > m_FileAccess.m_FileLen) {
56 return m_FileAccess.m_GetBlock(m_FileAccess.m_Param, offset,(FX_LPBYTE) buffer, size);
59 //0 bit: FPDF_POLICY_MACHINETIME_ACCESS
60 static FX_DWORD foxit_sandbox_policy = 0xFFFFFFFF;
62 void FSDK_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enable)
66 case FPDF_POLICY_MACHINETIME_ACCESS:
69 foxit_sandbox_policy |= 0x01;
71 foxit_sandbox_policy &= 0xFFFFFFFE;
79 FPDF_BOOL FSDK_IsSandBoxPolicyEnabled(FPDF_DWORD policy)
83 case FPDF_POLICY_MACHINETIME_ACCESS:
85 if(foxit_sandbox_policy&0x01)
103 CPDF_ModuleMgr* g_pModuleMgr = NULL;
105 CCodec_ModuleMgr* g_pCodecModule = NULL;
108 //extern CPDFSDK_FormFillApp* g_pFormFillApp;
110 #if _FX_OS_ == _FX_LINUX_EMBEDDED_
111 class CFontMapper : public IPDF_FontMapper
115 virtual ~CFontMapper();
117 virtual FT_Face FindSubstFont(
118 CPDF_Document* pDoc, // [IN] The PDF document
119 const CFX_ByteString& face_name, // [IN] Original name
120 FX_BOOL bTrueType, // [IN] TrueType or Type1
121 FX_DWORD flags, // [IN] PDF font flags (see PDF Reference section 5.7.1)
122 int font_weight, // [IN] original font weight. 0 for not specified
123 int CharsetCP, // [IN] code page for charset (see Win32 GetACP())
125 CPDF_SubstFont* pSubstFont // [OUT] Subst font data
131 CFontMapper* g_pFontMapper = NULL;
132 #endif // #if _FX_OS_ == _FX_LINUX_EMBEDDED_
134 DLLEXPORT void STDCALL FPDF_InitLibrary(FX_LPVOID hInstance)
137 CPDF_ModuleMgr::Create();
138 g_pModuleMgr = CPDF_ModuleMgr::Get();
139 #if _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_LINUX_EMBEDDED_
140 g_pModuleMgr->InitEmbedded();
142 g_pModuleMgr->LoadEmbeddedGB1CMaps();
145 g_pModuleMgr->LoadEmbeddedGB1CMaps_4();
148 g_pModuleMgr->LoadEmbeddedCNS1CMaps();
150 #ifdef _JAPAN1_CMAPS_
151 g_pModuleMgr->LoadEmbeddedJapan1CMaps();
153 #ifdef _JAPAN1_CMAPS_6_
154 g_pModuleMgr->LoadEmbeddedJapan1CMaps_6();
156 #ifdef _KOREA1_CMAPS_
157 g_pModuleMgr->LoadEmbeddedKorea1CMaps();
160 g_pModuleMgr->InitJpxModule();
161 g_pModuleMgr->InitJbig2Module();
162 // g_pModuleMgr->InitIccModule();
165 g_pModuleMgr->InitDesktop();
168 g_pCodecModule = CCodec_ModuleMgr::Create();
170 CFX_GEModule::Create();
171 CFX_GEModule::Get()->SetCodecModule(g_pCodecModule);
173 CPDF_ModuleMgr::Create();
174 CPDF_ModuleMgr::Get()->SetCodecModule(g_pCodecModule);
175 CPDF_ModuleMgr::Get()->InitPageModule();
176 CPDF_ModuleMgr::Get()->InitRenderModule();
177 #ifdef FOXIT_CHROME_BUILD
178 CPDF_ModuleMgr * pModuleMgr = CPDF_ModuleMgr::Get();
181 pModuleMgr->LoadEmbeddedGB1CMaps();
182 pModuleMgr->LoadEmbeddedJapan1CMaps();
183 pModuleMgr->LoadEmbeddedCNS1CMaps();
184 pModuleMgr->LoadEmbeddedKorea1CMaps();
191 TCHAR app_path[MAX_PATH];
192 ::GetModuleFileName((HINSTANCE)hInstance, app_path, MAX_PATH);
193 size_t len = _tcslen(app_path);
194 for (size_t i = len; i >= 0; i --)
195 if (app_path[i] == '\\') {
201 #ifndef _FXSDK_OPENSOURCE_
202 CPDF_ModuleMgr::Get()->SetModulePath(NULL, CFX_ByteString::FromUnicode(app_path));
205 #ifndef _FXSDK_OPENSOURCE_
206 CPDF_ModuleMgr::Get()->SetModulePath(NULL, app_path);
213 DLLEXPORT void STDCALL FPDF_DestroyLibrary()
216 #if _FX_OS_ == _FX_LINUX_EMBEDDED_
217 if (g_pFontMapper) delete g_pFontMapper;
220 g_pModuleMgr->Destroy();
222 CPDF_ModuleMgr::Destroy();
223 CFX_GEModule::Destroy();
224 g_pCodecModule->Destroy();
226 #ifndef _FXSDK_OPENSOURCE_
227 FXMEM_CollectAll(FXMEM_GetDefaultMgr());
235 void SetLastError(int err)
246 void ProcessParseError(FX_DWORD err_code)
248 // Translate FPDFAPI error code to FPDFVIEW error code
250 case PDFPARSE_ERROR_FILE:
251 err_code = FPDF_ERR_FILE;
253 case PDFPARSE_ERROR_FORMAT:
254 err_code = FPDF_ERR_FORMAT;
256 case PDFPARSE_ERROR_PASSWORD:
257 err_code = FPDF_ERR_PASSWORD;
259 case PDFPARSE_ERROR_HANDLER:
260 err_code = FPDF_ERR_SECURITY;
263 SetLastError(err_code);
266 DLLEXPORT void STDCALL FPDF_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enable)
268 return FSDK_SetSandBoxPolicy(policy, enable);
271 DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadDocument(FPDF_STRING file_path, FPDF_BYTESTRING password)
273 CPDF_Parser* pParser = FX_NEW CPDF_Parser;
274 pParser->SetPassword(password);
276 FX_DWORD err_code = pParser->StartParse((FX_LPCSTR)file_path);
279 ProcessParseError(err_code);
282 return pParser->GetDocument();
285 extern void CheckUnSupportError(CPDF_Document * pDoc, FX_DWORD err_code);
287 class CMemFile FX_FINAL: public IFX_FileRead, public CFX_Object
290 CMemFile(FX_BYTE* pBuf, FX_FILESIZE size):m_pBuf(pBuf),m_size(size) {}
292 virtual void Release() {delete this;}
293 virtual FX_FILESIZE GetSize() {return m_size;}
294 virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size)
299 FX_SAFE_FILESIZE newPos = base::checked_cast<FX_FILESIZE, size_t>(size);
301 if (!newPos.IsValid() || newPos.ValueOrDie() > (FX_DWORD)m_size) {
304 FXSYS_memcpy(buffer, m_pBuf+offset, size);
311 DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadMemDocument(const void* data_buf, int size, FPDF_BYTESTRING password)
313 CPDF_Parser* pParser = FX_NEW CPDF_Parser;
314 pParser->SetPassword(password);
315 CMemFile* pMemFile = FX_NEW CMemFile((FX_BYTE*)data_buf, size);
316 FX_DWORD err_code = pParser->StartParse(pMemFile);
319 ProcessParseError(err_code);
322 CPDF_Document * pDoc = NULL;
323 pDoc = pParser?pParser->GetDocument():NULL;
324 CheckUnSupportError(pDoc, err_code);
325 return pParser->GetDocument();
328 DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadCustomDocument(FPDF_FILEACCESS* pFileAccess, FPDF_BYTESTRING password)
330 CPDF_Parser* pParser = FX_NEW CPDF_Parser;
331 pParser->SetPassword(password);
332 CPDF_CustomAccess* pFile = FX_NEW CPDF_CustomAccess(pFileAccess);
333 FX_DWORD err_code = pParser->StartParse(pFile);
336 ProcessParseError(err_code);
339 CPDF_Document * pDoc = NULL;
340 pDoc = pParser?pParser->GetDocument():NULL;
341 CheckUnSupportError(pDoc, err_code);
342 return pParser->GetDocument();
345 DLLEXPORT FPDF_BOOL STDCALL FPDF_GetFileVersion(FPDF_DOCUMENT doc, int* fileVersion)
347 if(!doc||!fileVersion) return FALSE;
349 CPDF_Document* pDoc = (CPDF_Document*)doc;
350 CPDF_Parser* pParser = (CPDF_Parser*)pDoc->GetParser();
353 *fileVersion = pParser->GetFileVersion();
357 // jabdelmalek: changed return type from FX_DWORD to build on Linux (and match header).
358 DLLEXPORT unsigned long STDCALL FPDF_GetDocPermissions(FPDF_DOCUMENT document)
360 if (document == NULL) return 0;
361 CPDF_Document*pDoc = (CPDF_Document*)document;
362 CPDF_Parser* pParser = (CPDF_Parser*)pDoc->GetParser();
363 CPDF_Dictionary* pDict = pParser->GetEncryptDict();
364 if (pDict == NULL) return (FX_DWORD)-1;
366 return pDict->GetInteger("P");
369 DLLEXPORT int STDCALL FPDF_GetPageCount(FPDF_DOCUMENT document)
371 if (document == NULL) return 0;
372 return ((CPDF_Document*)document)->GetPageCount();
375 DLLEXPORT FPDF_PAGE STDCALL FPDF_LoadPage(FPDF_DOCUMENT document, int page_index)
377 if (document == NULL) return NULL;
378 if (page_index < 0 || page_index >= FPDF_GetPageCount(document)) return NULL;
379 // CPDF_Parser* pParser = (CPDF_Parser*)document;
380 CPDF_Document* pDoc = (CPDF_Document*)document;
381 if (pDoc == NULL) return NULL;
382 CPDF_Dictionary* pDict = pDoc->GetPage(page_index);
383 if (pDict == NULL) return NULL;
384 CPDF_Page* pPage = FX_NEW CPDF_Page;
385 pPage->Load(pDoc, pDict);
386 pPage->ParseContent();
388 // CheckUnSupportError(pDoc, 0);
393 DLLEXPORT double STDCALL FPDF_GetPageWidth(FPDF_PAGE page)
397 return ((CPDF_Page*)page)->GetPageWidth();
400 DLLEXPORT double STDCALL FPDF_GetPageHeight(FPDF_PAGE page)
402 if (!page) return 0.0;
403 return ((CPDF_Page*)page)->GetPageHeight();
406 void DropContext(void* data)
408 delete (CRenderContext*)data;
411 void FPDF_RenderPage_Retail(CRenderContext* pContext, FPDF_PAGE page, int start_x, int start_y, int size_x, int size_y,
412 int rotate, int flags,FX_BOOL bNeedToRestore, IFSDK_PAUSE_Adapter * pause );
413 void (*Func_RenderPage)(CRenderContext*, FPDF_PAGE page, int start_x, int start_y, int size_x, int size_y,
414 int rotate, int flags,FX_BOOL bNeedToRestore, IFSDK_PAUSE_Adapter * pause ) = FPDF_RenderPage_Retail;
416 #if defined(_DEBUG) || defined(DEBUG)
421 DLLEXPORT void STDCALL FPDF_RenderPage(HDC dc, FPDF_PAGE page, int start_x, int start_y, int size_x, int size_y,
422 int rotate, int flags)
424 if (page==NULL) return;
425 CPDF_Page* pPage = (CPDF_Page*)page;
427 CRenderContext* pContext = FX_NEW CRenderContext;
428 pPage->SetPrivateData((void*)1, pContext, DropContext);
431 CFX_DIBitmap* pBitmap = NULL;
432 FX_BOOL bBackgroundAlphaNeeded=FALSE;
433 bBackgroundAlphaNeeded = pPage->BackgroundAlphaNeeded();
434 if (bBackgroundAlphaNeeded)
437 pBitmap = FX_NEW CFX_DIBitmap;
438 pBitmap->Create(size_x, size_y, FXDIB_Argb);
439 pBitmap->Clear(0x00ffffff);
440 #ifdef _SKIA_SUPPORT_
441 pContext->m_pDevice = FX_NEW CFX_SkiaDevice;
442 ((CFX_SkiaDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)pBitmap);
444 pContext->m_pDevice = FX_NEW CFX_FxgeDevice;
445 ((CFX_FxgeDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)pBitmap);
449 pContext->m_pDevice = FX_NEW CFX_WindowsDevice(dc);
451 Func_RenderPage(pContext, page, start_x, start_y, size_x, size_y, rotate, flags,TRUE,NULL);
453 if (bBackgroundAlphaNeeded)
457 CFX_WindowsDevice WinDC(dc);
459 if (WinDC.GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER)
461 CFX_DIBitmap* pDst = FX_NEW CFX_DIBitmap;
462 pDst->Create(pBitmap->GetWidth(), pBitmap->GetHeight(),FXDIB_Rgb32);
463 FXSYS_memcpy(pDst->GetBuffer(), pBitmap->GetBuffer(), pBitmap->GetPitch()*pBitmap->GetHeight());
464 // WinDC.SetDIBits(pDst,0,0);
465 WinDC.StretchDIBits(pDst,0,0,size_x,size_y);
469 WinDC.SetDIBits(pBitmap,0,0);
478 rect.right = start_x + size_x;
479 rect.bottom = start_y + size_y;
480 GetClipBox(dc, &cliprect);
481 IntersectRect(&rect, &rect, &cliprect);
482 int width = rect.right - rect.left;
483 int height = rect.bottom - rect.top;
488 sprintf(str, "Rendering DIB %d x %d", width, height);
489 CPDF_ModuleMgr::Get()->ReportError(999, str);
493 // Create a DIB section
495 BITMAPINFOHEADER bmih;
496 FXSYS_memset(&bmih, 0, sizeof bmih);
497 bmih.biSize = sizeof bmih;
498 bmih.biBitCount = 24;
499 bmih.biHeight = -height;
501 bmih.biWidth = width;
502 pContext->m_hBitmap = CreateDIBSection(dc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, &pBuffer, NULL, 0);
503 if (pContext->m_hBitmap == NULL) {
504 #if defined(DEBUG) || defined(_DEBUG)
506 sprintf(str, "Error CreateDIBSection: %d x %d, error code = %d", width, height, GetLastError());
507 CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, str);
509 CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, NULL);
512 FXSYS_memset(pBuffer, 0xff, height*((width*3+3)/4*4));
516 CPDF_ModuleMgr::Get()->ReportError(999, "DIBSection created");
520 // Create a device with this external buffer
521 pContext->m_pBitmap = FX_NEW CFX_DIBitmap;
522 pContext->m_pBitmap->Create(width, height, FXDIB_Rgb, (FX_LPBYTE)pBuffer);
523 pContext->m_pDevice = FX_NEW CPDF_FxgeDevice;
524 ((CPDF_FxgeDevice*)pContext->m_pDevice)->Attach(pContext->m_pBitmap);
527 CPDF_ModuleMgr::Get()->ReportError(999, "Ready for PDF rendering");
530 // output to bitmap device
531 Func_RenderPage(pContext, page, start_x - rect.left, start_y - rect.top, size_x, size_y, rotate, flags);
534 CPDF_ModuleMgr::Get()->ReportError(999, "Finished PDF rendering");
537 // Now output to real device
538 HDC hMemDC = CreateCompatibleDC(dc);
539 if (hMemDC == NULL) {
540 #if defined(DEBUG) || defined(_DEBUG)
542 sprintf(str, "Error CreateCompatibleDC. Error code = %d", GetLastError());
543 CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, str);
545 CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, NULL);
549 HGDIOBJ hOldBitmap = SelectObject(hMemDC, pContext->m_hBitmap);
552 CPDF_ModuleMgr::Get()->ReportError(999, "Ready for screen rendering");
555 BitBlt(dc, rect.left, rect.top, width, height, hMemDC, 0, 0, SRCCOPY);
556 SelectObject(hMemDC, hOldBitmap);
560 CPDF_ModuleMgr::Get()->ReportError(999, "Finished screen rendering");
564 if (bBackgroundAlphaNeeded)
571 pPage->RemovePrivateData((void*)1);
575 DLLEXPORT void STDCALL FPDF_RenderPageBitmap(FPDF_BITMAP bitmap, FPDF_PAGE page, int start_x, int start_y,
576 int size_x, int size_y, int rotate, int flags)
578 if (bitmap == NULL || page == NULL) return;
579 CPDF_Page* pPage = (CPDF_Page*)page;
582 CRenderContext* pContext = FX_NEW CRenderContext;
583 pPage->SetPrivateData((void*)1, pContext, DropContext);
584 #ifdef _SKIA_SUPPORT_
585 pContext->m_pDevice = FX_NEW CFX_SkiaDevice;
587 if (flags & FPDF_REVERSE_BYTE_ORDER)
588 ((CFX_SkiaDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)bitmap,0,TRUE);
590 ((CFX_SkiaDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)bitmap);
592 pContext->m_pDevice = FX_NEW CFX_FxgeDevice;
594 if (flags & FPDF_REVERSE_BYTE_ORDER)
595 ((CFX_FxgeDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)bitmap,0,TRUE);
597 ((CFX_FxgeDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)bitmap);
600 Func_RenderPage(pContext, page, start_x, start_y, size_x, size_y, rotate, flags,TRUE,NULL);
603 pPage->RemovePrivateData((void*)1);
606 DLLEXPORT void STDCALL FPDF_ClosePage(FPDF_PAGE page)
609 delete (CPDF_Page*)page;
613 DLLEXPORT void STDCALL FPDF_CloseDocument(FPDF_DOCUMENT document)
617 CPDF_Document* pDoc = (CPDF_Document*)document;
618 CPDF_Parser* pParser = (CPDF_Parser*)pDoc->GetParser();
628 DLLEXPORT unsigned long STDCALL FPDF_GetLastError()
630 return GetLastError();
633 DLLEXPORT void STDCALL FPDF_DeviceToPage(FPDF_PAGE page, int start_x, int start_y, int size_x, int size_y,
634 int rotate, int device_x, int device_y, double* page_x, double* page_y)
636 if (page == NULL || page_x == NULL || page_y == NULL) return;
637 CPDF_Page* pPage = (CPDF_Page*)page;
639 CPDF_Matrix page2device;
640 pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);
641 CPDF_Matrix device2page;
642 device2page.SetReverse(page2device);
644 FX_FLOAT page_x_f, page_y_f;
645 device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f, page_y_f);
647 *page_x = (page_x_f);
648 *page_y = (page_y_f);
651 DLLEXPORT void STDCALL FPDF_PageToDevice(FPDF_PAGE page, int start_x, int start_y, int size_x, int size_y,
652 int rotate, double page_x, double page_y, int* device_x, int* device_y)
654 if (page == NULL || device_x == NULL || device_y == NULL) return;
655 CPDF_Page* pPage = (CPDF_Page*)page;
657 CPDF_Matrix page2device;
658 pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);
660 FX_FLOAT device_x_f, device_y_f;
661 page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f, device_y_f);
663 *device_x = FXSYS_round(device_x_f);
664 *device_y = FXSYS_round(device_y_f);
667 DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_Create(int width, int height, int alpha)
669 CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap;
670 pBitmap->Create(width, height, alpha ? FXDIB_Argb : FXDIB_Rgb32);
674 DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_CreateEx(int width, int height, int format, void* first_scan, int stride)
676 FXDIB_Format fx_format;
678 case FPDFBitmap_Gray:
679 fx_format = FXDIB_8bppRgb;
682 fx_format = FXDIB_Rgb;
684 case FPDFBitmap_BGRx:
685 fx_format = FXDIB_Rgb32;
687 case FPDFBitmap_BGRA:
688 fx_format = FXDIB_Argb;
693 CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap;
694 pBitmap->Create(width, height, fx_format, (FX_LPBYTE)first_scan, stride);
698 DLLEXPORT void STDCALL FPDFBitmap_FillRect(FPDF_BITMAP bitmap, int left, int top, int width, int height, FPDF_DWORD color)
700 if (bitmap == NULL) return;
701 #ifdef _SKIA_SUPPORT_
702 CFX_SkiaDevice device;
704 CFX_FxgeDevice device;
706 device.Attach((CFX_DIBitmap*)bitmap);
707 if (!((CFX_DIBitmap*)bitmap)->HasAlpha()) color |= 0xFF000000;
708 FX_RECT rect(left, top, left+width, top+height);
709 device.FillRect(&rect, color);
712 DLLEXPORT void* STDCALL FPDFBitmap_GetBuffer(FPDF_BITMAP bitmap)
714 if (bitmap == NULL) return NULL;
715 return ((CFX_DIBitmap*)bitmap)->GetBuffer();
718 DLLEXPORT int STDCALL FPDFBitmap_GetWidth(FPDF_BITMAP bitmap)
720 if (bitmap == NULL) return 0;
721 return ((CFX_DIBitmap*)bitmap)->GetWidth();
724 DLLEXPORT int STDCALL FPDFBitmap_GetHeight(FPDF_BITMAP bitmap)
726 if (bitmap == NULL) return 0;
727 return ((CFX_DIBitmap*)bitmap)->GetHeight();
730 DLLEXPORT int STDCALL FPDFBitmap_GetStride(FPDF_BITMAP bitmap)
732 if (bitmap == NULL) return 0;
733 return ((CFX_DIBitmap*)bitmap)->GetPitch();
736 DLLEXPORT void STDCALL FPDFBitmap_Destroy(FPDF_BITMAP bitmap)
738 if (bitmap == NULL) return;
739 delete (CFX_DIBitmap*)bitmap;
742 void FPDF_RenderPage_Retail(CRenderContext* pContext, FPDF_PAGE page, int start_x, int start_y, int size_x, int size_y,
743 int rotate, int flags,FX_BOOL bNeedToRestore, IFSDK_PAUSE_Adapter * pause )
745 //#ifdef _LICENSED_BUILD_
746 CPDF_Page* pPage = (CPDF_Page*)page;
747 if (pPage == NULL) return;
749 if (!pContext->m_pOptions)
750 pContext->m_pOptions = new CPDF_RenderOptions;
751 // CPDF_RenderOptions options;
752 if (flags & FPDF_LCD_TEXT)
753 pContext->m_pOptions->m_Flags |= RENDER_CLEARTYPE;
755 pContext->m_pOptions->m_Flags &= ~RENDER_CLEARTYPE;
756 if (flags & FPDF_NO_NATIVETEXT)
757 pContext->m_pOptions->m_Flags |= RENDER_NO_NATIVETEXT;
758 if (flags & FPDF_RENDER_LIMITEDIMAGECACHE)
759 pContext->m_pOptions->m_Flags |= RENDER_LIMITEDIMAGECACHE;
760 if (flags & FPDF_RENDER_FORCEHALFTONE)
761 pContext->m_pOptions->m_Flags |= RENDER_FORCE_HALFTONE;
763 if (flags & FPDF_GRAYSCALE)
765 pContext->m_pOptions->m_ColorMode = RENDER_COLOR_GRAY;
766 pContext->m_pOptions->m_ForeColor = 0;
767 pContext->m_pOptions->m_BackColor = 0xffffff;
769 const CPDF_OCContext::UsageType usage = (flags & FPDF_PRINTING) ? CPDF_OCContext::Print : CPDF_OCContext::View;
771 pContext->m_pOptions->m_AddFlags = flags >> 8;
773 pContext->m_pOptions->m_pOCContext = new CPDF_OCContext(pPage->m_pDocument, usage);
776 CFX_AffineMatrix matrix;
777 pPage->GetDisplayMatrix(matrix, start_x, start_y, size_x, size_y, rotate);
781 clip.right = start_x + size_x;
783 clip.bottom = start_y + size_y;
784 pContext->m_pDevice->SaveState();
785 pContext->m_pDevice->SetClip_Rect(&clip);
787 pContext->m_pContext = FX_NEW CPDF_RenderContext;
788 pContext->m_pContext->Create(pPage);
789 pContext->m_pContext->AppendObjectList(pPage, &matrix);
791 if (flags & FPDF_ANNOT) {
792 pContext->m_pAnnots = FX_NEW CPDF_AnnotList(pPage);
793 FX_BOOL bPrinting = pContext->m_pDevice->GetDeviceClass() != FXDC_DISPLAY;
794 pContext->m_pAnnots->DisplayAnnots(pPage, pContext->m_pContext, bPrinting, &matrix, TRUE, NULL);
797 pContext->m_pRenderer = FX_NEW CPDF_ProgressiveRenderer;
798 pContext->m_pRenderer->Start(pContext->m_pContext, pContext->m_pDevice, pContext->m_pOptions, pause);
801 pContext->m_pDevice->RestoreState();
807 DLLEXPORT int STDCALL FPDF_GetPageSizeByIndex(FPDF_DOCUMENT document, int page_index, double* width, double* height)
809 CPDF_Document* pDoc = (CPDF_Document*)document;
813 CPDF_Dictionary* pDict = pDoc->GetPage(page_index);
814 if (pDict == NULL) return FALSE;
817 page.Load(pDoc, pDict);
818 *width = page.GetPageWidth();
819 *height = page.GetPageHeight();
824 DLLEXPORT FPDF_BOOL STDCALL FPDF_VIEWERREF_GetPrintScaling(FPDF_DOCUMENT document)
826 CPDF_Document* pDoc = (CPDF_Document*)document;
827 if (!pDoc) return TRUE;
828 CPDF_ViewerPreferences viewRef(pDoc);
829 return viewRef.PrintScaling();
832 DLLEXPORT int STDCALL FPDF_VIEWERREF_GetNumCopies(FPDF_DOCUMENT document)
834 CPDF_Document* pDoc = (CPDF_Document*)document;
836 CPDF_ViewerPreferences viewRef(pDoc);
837 return viewRef.NumCopies();
840 DLLEXPORT FPDF_PAGERANGE STDCALL FPDF_VIEWERREF_GetPrintPageRange(FPDF_DOCUMENT document)
842 CPDF_Document* pDoc = (CPDF_Document*)document;
843 if (!pDoc) return NULL;
844 CPDF_ViewerPreferences viewRef(pDoc);
845 return viewRef.PrintPageRange();
848 DLLEXPORT FPDF_DUPLEXTYPE STDCALL FPDF_VIEWERREF_GetDuplex(FPDF_DOCUMENT document)
850 CPDF_Document* pDoc = (CPDF_Document*)document;
851 if (!pDoc) return DuplexUndefined;
852 CPDF_ViewerPreferences viewRef(pDoc);
853 CFX_ByteString duplex = viewRef.Duplex();
854 if (FX_BSTRC("Simplex") == duplex)
856 if (FX_BSTRC("DuplexFlipShortEdge") == duplex)
857 return DuplexFlipShortEdge;
858 if (FX_BSTRC("DuplexFlipLongEdge") == duplex)
859 return DuplexFlipLongEdge;
860 return DuplexUndefined;
863 DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDestByName(FPDF_DOCUMENT document,FPDF_BYTESTRING name)
865 if (document == NULL)
867 if (name == NULL || name[0] == 0)
870 CPDF_Document* pDoc = (CPDF_Document*)document;
871 CPDF_NameTree name_tree(pDoc, FX_BSTRC("Dests"));
872 return name_tree.LookupNamedDest(pDoc, name);