• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CPDF_CustomAccess(FPDF_FILEACCESS * pFileAccess)14 CPDF_CustomAccess::CPDF_CustomAccess(FPDF_FILEACCESS* pFileAccess)
15 {
16 	m_FileAccess = *pFileAccess;
17 	m_BufferOffset = (FX_DWORD)-1;
18 }
19 
GetByte(FX_DWORD pos,FX_BYTE & ch)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 
GetBlock(FX_DWORD pos,FX_LPBYTE pBuf,FX_DWORD size)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 
ReadBlock(void * buffer,FX_FILESIZE offset,size_t size)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 
FSDK_SetSandBoxPolicy(FPDF_DWORD policy,FPDF_BOOL enable)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 
FSDK_IsSandBoxPolicyEnabled(FPDF_DWORD policy)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 
FPDF_InitLibrary(FX_LPVOID hInstance)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 
FPDF_DestroyLibrary()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;
SetLastError(int err)234 void SetLastError(int err)
235 {
236 	g_LastError = err;
237 }
238 
GetLastError()239 int GetLastError()
240 {
241 	return g_LastError;
242 }
243 #endif
244 
ProcessParseError(FX_DWORD err_code)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 
FPDF_SetSandBoxPolicy(FPDF_DWORD policy,FPDF_BOOL enable)265 DLLEXPORT void	STDCALL FPDF_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enable)
266 {
267 	return FSDK_SetSandBoxPolicy(policy, enable);
268 }
269 
FPDF_LoadDocument(FPDF_STRING file_path,FPDF_BYTESTRING password)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:
CMemFile(FX_BYTE * pBuf,FX_FILESIZE size)295 	CMemFile(FX_BYTE* pBuf, FX_FILESIZE size):m_pBuf(pBuf),m_size(size) {}
296 
Release()297 	virtual void			Release() {delete this;}
GetSize()298 	virtual FX_FILESIZE		GetSize() {return m_size;}
ReadBlock(void * buffer,FX_FILESIZE offset,size_t 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 };
FPDF_LoadMemDocument(const void * data_buf,int size,FPDF_BYTESTRING password)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 
FPDF_LoadCustomDocument(FPDF_FILEACCESS * pFileAccess,FPDF_BYTESTRING password)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 
FPDF_GetFileVersion(FPDF_DOCUMENT doc,int * fileVersion)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).
FPDF_GetDocPermissions(FPDF_DOCUMENT document)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 
FPDF_GetPageCount(FPDF_DOCUMENT document)381 DLLEXPORT int STDCALL FPDF_GetPageCount(FPDF_DOCUMENT document)
382 {
383 	if (document == NULL) return 0;
384 	return ((CPDF_Document*)document)->GetPageCount();
385 }
386 
FPDF_LoadPage(FPDF_DOCUMENT document,int page_index)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 
FPDF_GetPageWidth(FPDF_PAGE page)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 
FPDF_GetPageHeight(FPDF_PAGE page)418 DLLEXPORT double STDCALL FPDF_GetPageHeight(FPDF_PAGE page)
419 {
420 	if (!page) return 0.0;
421 	return ((CPDF_Page*)page)->GetPageHeight();
422 }
423 
DropContext(void * data)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)
FPDF_RenderPage(HDC dc,FPDF_PAGE page,int start_x,int start_y,int size_x,int size_y,int rotate,int flags)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 
FPDF_RenderPageBitmap(FPDF_BITMAP bitmap,FPDF_PAGE page,int start_x,int start_y,int size_x,int size_y,int rotate,int flags)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 
FPDF_ClosePage(FPDF_PAGE page)642 DLLEXPORT void STDCALL FPDF_ClosePage(FPDF_PAGE page)
643 {
644 	if (!page) return;
645 	delete (CPDF_Page*)page;
646 
647 }
648 
FPDF_CloseDocument(FPDF_DOCUMENT document)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 
FPDF_GetLastError()664 DLLEXPORT unsigned long STDCALL FPDF_GetLastError()
665 {
666 	return GetLastError();
667 }
668 
FPDF_DeviceToPage(FPDF_PAGE page,int start_x,int start_y,int size_x,int size_y,int rotate,int device_x,int device_y,double * page_x,double * page_y)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 
FPDF_PageToDevice(FPDF_PAGE page,int start_x,int start_y,int size_x,int size_y,int rotate,double page_x,double page_y,int * device_x,int * device_y)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 
FPDFBitmap_Create(int width,int height,int alpha)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 
FPDFBitmap_CreateEx(int width,int height,int format,void * first_scan,int stride)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 
FPDFBitmap_FillRect(FPDF_BITMAP bitmap,int left,int top,int width,int height,int red,int green,int blue,int alpha)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 
FPDFBitmap_GetBuffer(FPDF_BITMAP bitmap)749 DLLEXPORT void* STDCALL FPDFBitmap_GetBuffer(FPDF_BITMAP bitmap)
750 {
751 	if (bitmap == NULL) return NULL;
752 	return ((CFX_DIBitmap*)bitmap)->GetBuffer();
753 }
754 
FPDFBitmap_GetWidth(FPDF_BITMAP bitmap)755 DLLEXPORT int STDCALL FPDFBitmap_GetWidth(FPDF_BITMAP bitmap)
756 {
757 	if (bitmap == NULL) return 0;
758 	return ((CFX_DIBitmap*)bitmap)->GetWidth();
759 }
760 
FPDFBitmap_GetHeight(FPDF_BITMAP bitmap)761 DLLEXPORT int STDCALL FPDFBitmap_GetHeight(FPDF_BITMAP bitmap)
762 {
763 	if (bitmap == NULL) return 0;
764 	return ((CFX_DIBitmap*)bitmap)->GetHeight();
765 }
766 
FPDFBitmap_GetStride(FPDF_BITMAP bitmap)767 DLLEXPORT int STDCALL FPDFBitmap_GetStride(FPDF_BITMAP bitmap)
768 {
769 	if (bitmap == NULL) return 0;
770 	return ((CFX_DIBitmap*)bitmap)->GetPitch();
771 }
772 
FPDFBitmap_Destroy(FPDF_BITMAP bitmap)773 DLLEXPORT void STDCALL FPDFBitmap_Destroy(FPDF_BITMAP bitmap)
774 {
775 	if (bitmap == NULL) return;
776 	delete (CFX_DIBitmap*)bitmap;
777 }
778 
FPDF_RenderPage_Retail(CRenderContext * pContext,FPDF_PAGE page,int start_x,int start_y,int size_x,int size_y,int rotate,int flags,FX_BOOL bNeedToRestore,IFSDK_PAUSE_Adapter * pause)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 
FPDF_GetPageSizeByIndex(FPDF_DOCUMENT document,int page_index,double * width,double * height)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 
FPDF_VIEWERREF_GetPrintScaling(FPDF_DOCUMENT document)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 
FPDF_GetNamedDestByName(FPDF_DOCUMENT document,FPDF_BYTESTRING name)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