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