Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Side by Side Diff: fpdfsdk/src/fpdfview.cpp

Issue 1799773002: Move fpdfsdk/src up to fpdfsdk/. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Rebase to master Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « fpdfsdk/src/fpdftext_embeddertest.cpp ('k') | fpdfsdk/src/fpdfview_c_api_test.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "public/fpdfview.h"
8
9 #include <memory>
10
11 #include "core/include/fpdfapi/cpdf_array.h"
12 #include "core/include/fpdfapi/cpdf_document.h"
13 #include "core/include/fxcodec/fx_codec.h"
14 #include "core/include/fxcrt/fx_safe_types.h"
15 #include "fpdfsdk/include/fsdk_define.h"
16 #include "fpdfsdk/include/fsdk_mgr.h"
17 #include "fpdfsdk/include/fsdk_rendercontext.h"
18 #include "fpdfsdk/include/javascript/IJavaScript.h"
19 #include "public/fpdf_ext.h"
20 #include "public/fpdf_progressive.h"
21 #include "third_party/base/numerics/safe_conversions_impl.h"
22
23 #ifdef PDF_ENABLE_XFA
24 #include "core/include/fpdfapi/fpdf_module.h"
25 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"
26 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
27 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h"
28 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"
29 #include "public/fpdf_formfill.h"
30 #endif // PDF_ENABLE_XFA
31
32 UnderlyingDocumentType* UnderlyingFromFPDFDocument(FPDF_DOCUMENT doc) {
33 return static_cast<UnderlyingDocumentType*>(doc);
34 }
35
36 FPDF_DOCUMENT FPDFDocumentFromUnderlying(UnderlyingDocumentType* doc) {
37 return static_cast<FPDF_DOCUMENT>(doc);
38 }
39
40 UnderlyingPageType* UnderlyingFromFPDFPage(FPDF_PAGE page) {
41 return static_cast<UnderlyingPageType*>(page);
42 }
43
44 CPDF_Document* CPDFDocumentFromFPDFDocument(FPDF_DOCUMENT doc) {
45 #ifdef PDF_ENABLE_XFA
46 return doc ? UnderlyingFromFPDFDocument(doc)->GetPDFDoc() : nullptr;
47 #else // PDF_ENABLE_XFA
48 return UnderlyingFromFPDFDocument(doc);
49 #endif // PDF_ENABLE_XFA
50 }
51
52 FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc) {
53 #ifdef PDF_ENABLE_XFA
54 return doc ? FPDFDocumentFromUnderlying(
55 new CPDFXFA_Document(doc, CPDFXFA_App::GetInstance()))
56 : nullptr;
57 #else // PDF_ENABLE_XFA
58 return FPDFDocumentFromUnderlying(doc);
59 #endif // PDF_ENABLE_XFA
60 }
61
62 CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page) {
63 #ifdef PDF_ENABLE_XFA
64 return page ? UnderlyingFromFPDFPage(page)->GetPDFPage() : nullptr;
65 #else // PDF_ENABLE_XFA
66 return UnderlyingFromFPDFPage(page);
67 #endif // PDF_ENABLE_XFA
68 }
69
70 #ifdef PDF_ENABLE_XFA
71 CFPDF_FileStream::CFPDF_FileStream(FPDF_FILEHANDLER* pFS) {
72 m_pFS = pFS;
73 m_nCurPos = 0;
74 }
75
76 IFX_FileStream* CFPDF_FileStream::Retain() {
77 return this;
78 }
79
80 void CFPDF_FileStream::Release() {
81 if (m_pFS && m_pFS->Release)
82 m_pFS->Release(m_pFS->clientData);
83 delete this;
84 }
85
86 FX_FILESIZE CFPDF_FileStream::GetSize() {
87 if (m_pFS && m_pFS->GetSize)
88 return (FX_FILESIZE)m_pFS->GetSize(m_pFS->clientData);
89 return 0;
90 }
91
92 FX_BOOL CFPDF_FileStream::IsEOF() {
93 return m_nCurPos >= GetSize();
94 }
95
96 FX_BOOL CFPDF_FileStream::ReadBlock(void* buffer,
97 FX_FILESIZE offset,
98 size_t size) {
99 if (!buffer || !size || !m_pFS->ReadBlock)
100 return FALSE;
101
102 if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer,
103 (FPDF_DWORD)size) == 0) {
104 m_nCurPos = offset + size;
105 return TRUE;
106 }
107 return FALSE;
108 }
109
110 size_t CFPDF_FileStream::ReadBlock(void* buffer, size_t size) {
111 if (!buffer || !size || !m_pFS->ReadBlock)
112 return 0;
113
114 FX_FILESIZE nSize = GetSize();
115 if (m_nCurPos >= nSize)
116 return 0;
117 FX_FILESIZE dwAvail = nSize - m_nCurPos;
118 if (dwAvail < (FX_FILESIZE)size)
119 size = (size_t)dwAvail;
120 if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)m_nCurPos, buffer,
121 (FPDF_DWORD)size) == 0) {
122 m_nCurPos += size;
123 return size;
124 }
125
126 return 0;
127 }
128
129 FX_BOOL CFPDF_FileStream::WriteBlock(const void* buffer,
130 FX_FILESIZE offset,
131 size_t size) {
132 if (!m_pFS || !m_pFS->WriteBlock)
133 return FALSE;
134
135 if (m_pFS->WriteBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer,
136 (FPDF_DWORD)size) == 0) {
137 m_nCurPos = offset + size;
138 return TRUE;
139 }
140 return FALSE;
141 }
142
143 FX_BOOL CFPDF_FileStream::Flush() {
144 if (!m_pFS || !m_pFS->Flush)
145 return TRUE;
146
147 return m_pFS->Flush(m_pFS->clientData) == 0;
148 }
149 #endif // PDF_ENABLE_XFA
150
151 CPDF_CustomAccess::CPDF_CustomAccess(FPDF_FILEACCESS* pFileAccess) {
152 m_FileAccess = *pFileAccess;
153 #ifdef PDF_ENABLE_XFA
154 m_BufferOffset = (FX_DWORD)-1;
155 #endif // PDF_ENABLE_XFA
156 }
157
158 #ifdef PDF_ENABLE_XFA
159 FX_BOOL CPDF_CustomAccess::GetByte(FX_DWORD pos, uint8_t& ch) {
160 if (pos >= m_FileAccess.m_FileLen)
161 return FALSE;
162 if (m_BufferOffset == (FX_DWORD)-1 || pos < m_BufferOffset ||
163 pos >= m_BufferOffset + 512) {
164 // Need to read from file access
165 m_BufferOffset = pos;
166 int size = 512;
167 if (pos + 512 > m_FileAccess.m_FileLen)
168 size = m_FileAccess.m_FileLen - pos;
169 if (!m_FileAccess.m_GetBlock(m_FileAccess.m_Param, m_BufferOffset, m_Buffer,
170 size))
171 return FALSE;
172 }
173 ch = m_Buffer[pos - m_BufferOffset];
174 return TRUE;
175 }
176
177 FX_BOOL CPDF_CustomAccess::GetBlock(FX_DWORD pos,
178 uint8_t* pBuf,
179 FX_DWORD size) {
180 if (pos + size > m_FileAccess.m_FileLen)
181 return FALSE;
182 return m_FileAccess.m_GetBlock(m_FileAccess.m_Param, pos, pBuf, size);
183 }
184 #endif // PDF_ENABLE_XFA
185
186 FX_BOOL CPDF_CustomAccess::ReadBlock(void* buffer,
187 FX_FILESIZE offset,
188 size_t size) {
189 if (offset < 0) {
190 return FALSE;
191 }
192 FX_SAFE_FILESIZE newPos =
193 pdfium::base::checked_cast<FX_FILESIZE, size_t>(size);
194 newPos += offset;
195 if (!newPos.IsValid() || newPos.ValueOrDie() > m_FileAccess.m_FileLen) {
196 return FALSE;
197 }
198 return m_FileAccess.m_GetBlock(m_FileAccess.m_Param, offset, (uint8_t*)buffer,
199 size);
200 }
201
202 // 0 bit: FPDF_POLICY_MACHINETIME_ACCESS
203 static FX_DWORD foxit_sandbox_policy = 0xFFFFFFFF;
204
205 void FSDK_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enable) {
206 switch (policy) {
207 case FPDF_POLICY_MACHINETIME_ACCESS: {
208 if (enable)
209 foxit_sandbox_policy |= 0x01;
210 else
211 foxit_sandbox_policy &= 0xFFFFFFFE;
212 } break;
213 default:
214 break;
215 }
216 }
217
218 FPDF_BOOL FSDK_IsSandBoxPolicyEnabled(FPDF_DWORD policy) {
219 switch (policy) {
220 case FPDF_POLICY_MACHINETIME_ACCESS:
221 return !!(foxit_sandbox_policy & 0x01);
222 default:
223 return FALSE;
224 }
225 }
226
227 CCodec_ModuleMgr* g_pCodecModule = nullptr;
228
229 DLLEXPORT void STDCALL FPDF_InitLibrary() {
230 FPDF_InitLibraryWithConfig(nullptr);
231 }
232
233 DLLEXPORT void STDCALL FPDF_InitLibraryWithConfig(
234 const FPDF_LIBRARY_CONFIG* cfg) {
235 g_pCodecModule = new CCodec_ModuleMgr();
236
237 CFX_GEModule::Create(cfg ? cfg->m_pUserFontPaths : nullptr);
238 CFX_GEModule::Get()->SetCodecModule(g_pCodecModule);
239
240 CPDF_ModuleMgr::Create();
241 CPDF_ModuleMgr* pModuleMgr = CPDF_ModuleMgr::Get();
242 pModuleMgr->SetCodecModule(g_pCodecModule);
243 pModuleMgr->InitPageModule();
244 pModuleMgr->InitRenderModule();
245 #ifdef PDF_ENABLE_XFA
246 CPDFXFA_App::GetInstance()->Initialize(
247 (cfg && cfg->version >= 2)
248 ? reinterpret_cast<FXJSE_HRUNTIME>(cfg->m_pIsolate)
249 : nullptr);
250 #else // PDF_ENABLE_XFA
251 pModuleMgr->LoadEmbeddedGB1CMaps();
252 pModuleMgr->LoadEmbeddedJapan1CMaps();
253 pModuleMgr->LoadEmbeddedCNS1CMaps();
254 pModuleMgr->LoadEmbeddedKorea1CMaps();
255 #endif // PDF_ENABLE_XFA
256 if (cfg && cfg->version >= 2)
257 IJS_Runtime::Initialize(cfg->m_v8EmbedderSlot, cfg->m_pIsolate);
258 }
259
260 DLLEXPORT void STDCALL FPDF_DestroyLibrary() {
261 #ifdef PDF_ENABLE_XFA
262 CPDFXFA_App::ReleaseInstance();
263 #endif // PDF_ENABLE_XFA
264 CPDF_ModuleMgr::Destroy();
265 CFX_GEModule::Destroy();
266
267 delete g_pCodecModule;
268 g_pCodecModule = nullptr;
269 }
270
271 #ifndef _WIN32
272 int g_LastError;
273 void SetLastError(int err) {
274 g_LastError = err;
275 }
276
277 int GetLastError() {
278 return g_LastError;
279 }
280 #endif // _WIN32
281
282 void ProcessParseError(CPDF_Parser::Error err) {
283 FX_DWORD err_code;
284 // Translate FPDFAPI error code to FPDFVIEW error code
285 switch (err) {
286 case CPDF_Parser::SUCCESS:
287 err_code = FPDF_ERR_SUCCESS;
288 break;
289 case CPDF_Parser::FILE_ERROR:
290 err_code = FPDF_ERR_FILE;
291 break;
292 case CPDF_Parser::FORMAT_ERROR:
293 err_code = FPDF_ERR_FORMAT;
294 break;
295 case CPDF_Parser::PASSWORD_ERROR:
296 err_code = FPDF_ERR_PASSWORD;
297 break;
298 case CPDF_Parser::HANDLER_ERROR:
299 err_code = FPDF_ERR_SECURITY;
300 break;
301 }
302 SetLastError(err_code);
303 }
304
305 DLLEXPORT void STDCALL FPDF_SetSandBoxPolicy(FPDF_DWORD policy,
306 FPDF_BOOL enable) {
307 return FSDK_SetSandBoxPolicy(policy, enable);
308 }
309
310 DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadDocument(FPDF_STRING file_path,
311 FPDF_BYTESTRING password) {
312 // NOTE: the creation of the file needs to be by the embedder on the
313 // other side of this API.
314 IFX_FileRead* pFileAccess = FX_CreateFileRead((const FX_CHAR*)file_path);
315 if (!pFileAccess) {
316 return nullptr;
317 }
318
319 CPDF_Parser* pParser = new CPDF_Parser;
320 pParser->SetPassword(password);
321
322 CPDF_Parser::Error error = pParser->StartParse(pFileAccess);
323 if (error != CPDF_Parser::SUCCESS) {
324 delete pParser;
325 ProcessParseError(error);
326 return NULL;
327 }
328 #ifdef PDF_ENABLE_XFA
329 CPDF_Document* pPDFDoc = pParser->GetDocument();
330 if (!pPDFDoc)
331 return NULL;
332
333 CPDFXFA_App* pProvider = CPDFXFA_App::GetInstance();
334 return new CPDFXFA_Document(pPDFDoc, pProvider);
335 #else // PDF_ENABLE_XFA
336 return pParser->GetDocument();
337 #endif // PDF_ENABLE_XFA
338 }
339
340 #ifdef PDF_ENABLE_XFA
341 DLLEXPORT FPDF_BOOL STDCALL FPDF_HasXFAField(FPDF_DOCUMENT document,
342 int* docType) {
343 if (!document)
344 return FALSE;
345
346 CPDF_Document* pdfDoc =
347 (static_cast<CPDFXFA_Document*>(document))->GetPDFDoc();
348 if (!pdfDoc)
349 return FALSE;
350
351 CPDF_Dictionary* pRoot = pdfDoc->GetRoot();
352 if (!pRoot)
353 return FALSE;
354
355 CPDF_Dictionary* pAcroForm = pRoot->GetDictBy("AcroForm");
356 if (!pAcroForm)
357 return FALSE;
358
359 CPDF_Object* pXFA = pAcroForm->GetElement("XFA");
360 if (!pXFA)
361 return FALSE;
362
363 FX_BOOL bDynamicXFA = pRoot->GetBooleanBy("NeedsRendering", FALSE);
364
365 if (bDynamicXFA)
366 *docType = DOCTYPE_DYNAMIC_XFA;
367 else
368 *docType = DOCTYPE_STATIC_XFA;
369
370 return TRUE;
371 }
372
373 DLLEXPORT FPDF_BOOL STDCALL FPDF_LoadXFA(FPDF_DOCUMENT document) {
374 return document && (static_cast<CPDFXFA_Document*>(document))->LoadXFADoc();
375 }
376 #endif // PDF_ENABLE_XFA
377
378 class CMemFile final : public IFX_FileRead {
379 public:
380 CMemFile(uint8_t* pBuf, FX_FILESIZE size) : m_pBuf(pBuf), m_size(size) {}
381
382 void Release() override { delete this; }
383 FX_FILESIZE GetSize() override { return m_size; }
384 FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override {
385 if (offset < 0) {
386 return FALSE;
387 }
388 FX_SAFE_FILESIZE newPos =
389 pdfium::base::checked_cast<FX_FILESIZE, size_t>(size);
390 newPos += offset;
391 if (!newPos.IsValid() || newPos.ValueOrDie() > (FX_DWORD)m_size) {
392 return FALSE;
393 }
394 FXSYS_memcpy(buffer, m_pBuf + offset, size);
395 return TRUE;
396 }
397
398 private:
399 ~CMemFile() override {}
400
401 uint8_t* const m_pBuf;
402 const FX_FILESIZE m_size;
403 };
404
405 DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadMemDocument(const void* data_buf,
406 int size,
407 FPDF_BYTESTRING password) {
408 CPDF_Parser* pParser = new CPDF_Parser;
409 pParser->SetPassword(password);
410 CMemFile* pMemFile = new CMemFile((uint8_t*)data_buf, size);
411 CPDF_Parser::Error error = pParser->StartParse(pMemFile);
412 if (error != CPDF_Parser::SUCCESS) {
413 delete pParser;
414 ProcessParseError(error);
415 return NULL;
416 }
417 CPDF_Document* pDoc = NULL;
418 pDoc = pParser ? pParser->GetDocument() : NULL;
419 CheckUnSupportError(pDoc, error);
420 return FPDFDocumentFromCPDFDocument(pParser->GetDocument());
421 }
422
423 DLLEXPORT FPDF_DOCUMENT STDCALL
424 FPDF_LoadCustomDocument(FPDF_FILEACCESS* pFileAccess,
425 FPDF_BYTESTRING password) {
426 CPDF_Parser* pParser = new CPDF_Parser;
427 pParser->SetPassword(password);
428 CPDF_CustomAccess* pFile = new CPDF_CustomAccess(pFileAccess);
429 CPDF_Parser::Error error = pParser->StartParse(pFile);
430 if (error != CPDF_Parser::SUCCESS) {
431 delete pParser;
432 ProcessParseError(error);
433 return NULL;
434 }
435 CPDF_Document* pDoc = NULL;
436 pDoc = pParser ? pParser->GetDocument() : NULL;
437 CheckUnSupportError(pDoc, error);
438 return FPDFDocumentFromCPDFDocument(pParser->GetDocument());
439 }
440
441 DLLEXPORT FPDF_BOOL STDCALL FPDF_GetFileVersion(FPDF_DOCUMENT doc,
442 int* fileVersion) {
443 if (!fileVersion)
444 return FALSE;
445
446 *fileVersion = 0;
447 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(doc);
448 if (!pDoc)
449 return FALSE;
450
451 CPDF_Parser* pParser = pDoc->GetParser();
452 if (!pParser)
453 return FALSE;
454
455 *fileVersion = pParser->GetFileVersion();
456 return TRUE;
457 }
458
459 // jabdelmalek: changed return type from FX_DWORD to build on Linux (and match
460 // header).
461 DLLEXPORT unsigned long STDCALL FPDF_GetDocPermissions(FPDF_DOCUMENT document) {
462 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
463 if (!pDoc)
464 #ifndef PDF_ENABLE_XFA
465 return 0;
466 #else // PDF_ENABLE_XFA
467 return (FX_DWORD)-1;
468 #endif // PDF_ENABLE_XFA
469
470 CPDF_Dictionary* pDict = pDoc->GetParser()->GetEncryptDict();
471 return pDict ? pDict->GetIntegerBy("P") : (FX_DWORD)-1;
472 }
473
474 DLLEXPORT int STDCALL FPDF_GetSecurityHandlerRevision(FPDF_DOCUMENT document) {
475 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
476 if (!pDoc)
477 return -1;
478
479 CPDF_Dictionary* pDict = pDoc->GetParser()->GetEncryptDict();
480 return pDict ? pDict->GetIntegerBy("R") : -1;
481 }
482
483 DLLEXPORT int STDCALL FPDF_GetPageCount(FPDF_DOCUMENT document) {
484 UnderlyingDocumentType* pDoc = UnderlyingFromFPDFDocument(document);
485 return pDoc ? pDoc->GetPageCount() : 0;
486 }
487
488 DLLEXPORT FPDF_PAGE STDCALL FPDF_LoadPage(FPDF_DOCUMENT document,
489 int page_index) {
490 UnderlyingDocumentType* pDoc = UnderlyingFromFPDFDocument(document);
491 if (!pDoc)
492 return nullptr;
493
494 if (page_index < 0 || page_index >= pDoc->GetPageCount())
495 return nullptr;
496
497 #ifdef PDF_ENABLE_XFA
498 return pDoc->GetPage(page_index);
499 #else // PDF_ENABLE_XFA
500 CPDF_Dictionary* pDict = pDoc->GetPage(page_index);
501 if (!pDict)
502 return NULL;
503 CPDF_Page* pPage = new CPDF_Page;
504 pPage->Load(pDoc, pDict);
505 pPage->ParseContent(nullptr);
506 return pPage;
507 #endif // PDF_ENABLE_XFA
508 }
509
510 DLLEXPORT double STDCALL FPDF_GetPageWidth(FPDF_PAGE page) {
511 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
512 return pPage ? pPage->GetPageWidth() : 0.0;
513 }
514
515 DLLEXPORT double STDCALL FPDF_GetPageHeight(FPDF_PAGE page) {
516 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
517 return pPage ? pPage->GetPageHeight() : 0.0;
518 }
519
520 void DropContext(void* data) {
521 delete (CRenderContext*)data;
522 }
523
524 #if defined(_WIN32)
525 DLLEXPORT void STDCALL FPDF_RenderPage(HDC dc,
526 FPDF_PAGE page,
527 int start_x,
528 int start_y,
529 int size_x,
530 int size_y,
531 int rotate,
532 int flags) {
533 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
534 if (!pPage)
535 return;
536
537 CRenderContext* pContext = new CRenderContext;
538 pPage->SetPrivateData((void*)1, pContext, DropContext);
539
540 #if !defined(_WIN32_WCE)
541 CFX_DIBitmap* pBitmap = nullptr;
542 FX_BOOL bBackgroundAlphaNeeded = pPage->BackgroundAlphaNeeded();
543 FX_BOOL bHasImageMask = pPage->HasImageMask();
544 if (bBackgroundAlphaNeeded || bHasImageMask) {
545 pBitmap = new CFX_DIBitmap;
546 pBitmap->Create(size_x, size_y, FXDIB_Argb);
547 pBitmap->Clear(0x00ffffff);
548 #ifdef _SKIA_SUPPORT_
549 pContext->m_pDevice = new CFX_SkiaDevice;
550 ((CFX_SkiaDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)pBitmap);
551 #else
552 pContext->m_pDevice = new CFX_FxgeDevice;
553 ((CFX_FxgeDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)pBitmap);
554 #endif
555 } else {
556 pContext->m_pDevice = new CFX_WindowsDevice(dc);
557 }
558
559 FPDF_RenderPage_Retail(pContext, page, start_x, start_y, size_x, size_y,
560 rotate, flags, TRUE, NULL);
561
562 if (bBackgroundAlphaNeeded || bHasImageMask) {
563 if (pBitmap) {
564 CFX_WindowsDevice WinDC(dc);
565
566 if (WinDC.GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) {
567 CFX_DIBitmap* pDst = new CFX_DIBitmap;
568 int pitch = pBitmap->GetPitch();
569 pDst->Create(size_x, size_y, FXDIB_Rgb32);
570 FXSYS_memset(pDst->GetBuffer(), -1, pitch * size_y);
571 pDst->CompositeBitmap(0, 0, size_x, size_y, pBitmap, 0, 0,
572 FXDIB_BLEND_NORMAL, NULL, FALSE, NULL);
573 WinDC.StretchDIBits(pDst, 0, 0, size_x, size_y);
574 delete pDst;
575 } else {
576 WinDC.SetDIBits(pBitmap, 0, 0);
577 }
578 }
579 }
580 #else
581 // get clip region
582 RECT rect, cliprect;
583 rect.left = start_x;
584 rect.top = start_y;
585 rect.right = start_x + size_x;
586 rect.bottom = start_y + size_y;
587 GetClipBox(dc, &cliprect);
588 IntersectRect(&rect, &rect, &cliprect);
589 int width = rect.right - rect.left;
590 int height = rect.bottom - rect.top;
591
592 // Create a DIB section
593 LPVOID pBuffer;
594 BITMAPINFOHEADER bmih;
595 FXSYS_memset(&bmih, 0, sizeof bmih);
596 bmih.biSize = sizeof bmih;
597 bmih.biBitCount = 24;
598 bmih.biHeight = -height;
599 bmih.biPlanes = 1;
600 bmih.biWidth = width;
601 pContext->m_hBitmap = CreateDIBSection(dc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS,
602 &pBuffer, NULL, 0);
603 FXSYS_memset(pBuffer, 0xff, height * ((width * 3 + 3) / 4 * 4));
604
605 // Create a device with this external buffer
606 pContext->m_pBitmap = new CFX_DIBitmap;
607 pContext->m_pBitmap->Create(width, height, FXDIB_Rgb, (uint8_t*)pBuffer);
608 pContext->m_pDevice = new CPDF_FxgeDevice;
609 ((CPDF_FxgeDevice*)pContext->m_pDevice)->Attach(pContext->m_pBitmap);
610
611 // output to bitmap device
612 FPDF_RenderPage_Retail(pContext, page, start_x - rect.left,
613 start_y - rect.top, size_x, size_y, rotate, flags);
614
615 // Now output to real device
616 HDC hMemDC = CreateCompatibleDC(dc);
617 HGDIOBJ hOldBitmap = SelectObject(hMemDC, pContext->m_hBitmap);
618
619 BitBlt(dc, rect.left, rect.top, width, height, hMemDC, 0, 0, SRCCOPY);
620 SelectObject(hMemDC, hOldBitmap);
621 DeleteDC(hMemDC);
622
623 #endif // !defined(_WIN32_WCE)
624 if (bBackgroundAlphaNeeded || bHasImageMask)
625 delete pBitmap;
626
627 delete pContext;
628 pPage->RemovePrivateData((void*)1);
629 }
630 #endif // defined(_WIN32)
631
632 DLLEXPORT void STDCALL FPDF_RenderPageBitmap(FPDF_BITMAP bitmap,
633 FPDF_PAGE page,
634 int start_x,
635 int start_y,
636 int size_x,
637 int size_y,
638 int rotate,
639 int flags) {
640 if (!bitmap)
641 return;
642 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
643 if (!pPage)
644 return;
645 CRenderContext* pContext = new CRenderContext;
646 pPage->SetPrivateData((void*)1, pContext, DropContext);
647 #ifdef _SKIA_SUPPORT_
648 pContext->m_pDevice = new CFX_SkiaDevice;
649
650 if (flags & FPDF_REVERSE_BYTE_ORDER)
651 ((CFX_SkiaDevice*)pContext->m_pDevice)
652 ->Attach((CFX_DIBitmap*)bitmap, 0, TRUE);
653 else
654 ((CFX_SkiaDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)bitmap);
655 #else
656 pContext->m_pDevice = new CFX_FxgeDevice;
657
658 if (flags & FPDF_REVERSE_BYTE_ORDER)
659 ((CFX_FxgeDevice*)pContext->m_pDevice)
660 ->Attach((CFX_DIBitmap*)bitmap, 0, TRUE);
661 else
662 ((CFX_FxgeDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)bitmap);
663 #endif
664
665 FPDF_RenderPage_Retail(pContext, page, start_x, start_y, size_x, size_y,
666 rotate, flags, TRUE, NULL);
667
668 delete pContext;
669 pPage->RemovePrivateData((void*)1);
670 }
671
672 DLLEXPORT void STDCALL FPDF_ClosePage(FPDF_PAGE page) {
673 if (!page)
674 return;
675 #ifdef PDF_ENABLE_XFA
676 CPDFXFA_Page* pPage = (CPDFXFA_Page*)page;
677 pPage->Release();
678 #else // PDF_ENABLE_XFA
679 CPDFSDK_PageView* pPageView =
680 (CPDFSDK_PageView*)(((CPDF_Page*)page))->GetPrivateData((void*)page);
681 if (pPageView && pPageView->IsLocked()) {
682 pPageView->TakeOverPage();
683 return;
684 }
685 delete (CPDF_Page*)page;
686 #endif // PDF_ENABLE_XFA
687 }
688
689 DLLEXPORT void STDCALL FPDF_CloseDocument(FPDF_DOCUMENT document) {
690 #ifdef PDF_ENABLE_XFA
691 delete UnderlyingFromFPDFDocument(document);
692 #else // PDF_ENABLE_XFA
693 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
694 if (!pDoc)
695 return;
696 CPDF_Parser* pParser = pDoc->GetParser();
697 if (!pParser) {
698 delete pDoc;
699 return;
700 }
701 delete pParser;
702 #endif // PDF_ENABLE_XFA
703 }
704
705 DLLEXPORT unsigned long STDCALL FPDF_GetLastError() {
706 return GetLastError();
707 }
708
709 DLLEXPORT void STDCALL FPDF_DeviceToPage(FPDF_PAGE page,
710 int start_x,
711 int start_y,
712 int size_x,
713 int size_y,
714 int rotate,
715 int device_x,
716 int device_y,
717 double* page_x,
718 double* page_y) {
719 if (!page || !page_x || !page_y)
720 return;
721 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
722 #ifdef PDF_ENABLE_XFA
723 pPage->DeviceToPage(start_x, start_y, size_x, size_y, rotate, device_x,
724 device_y, page_x, page_y);
725 #else // PDF_ENABLE_XFA
726 CFX_Matrix page2device;
727 pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y,
728 rotate);
729 CFX_Matrix device2page;
730 device2page.SetReverse(page2device);
731 FX_FLOAT page_x_f, page_y_f;
732 device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f,
733 page_y_f);
734 *page_x = (page_x_f);
735 *page_y = (page_y_f);
736 #endif // PDF_ENABLE_XFA
737 }
738
739 DLLEXPORT void STDCALL FPDF_PageToDevice(FPDF_PAGE page,
740 int start_x,
741 int start_y,
742 int size_x,
743 int size_y,
744 int rotate,
745 double page_x,
746 double page_y,
747 int* device_x,
748 int* device_y) {
749 if (!device_x || !device_y)
750 return;
751 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
752 if (!pPage)
753 return;
754 #ifdef PDF_ENABLE_XFA
755 pPage->PageToDevice(start_x, start_y, size_x, size_y, rotate, page_x, page_y,
756 device_x, device_y);
757 #else // PDF_ENABLE_XFA
758 CFX_Matrix page2device;
759 pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y,
760 rotate);
761 FX_FLOAT device_x_f, device_y_f;
762 page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f,
763 device_y_f);
764 *device_x = FXSYS_round(device_x_f);
765 *device_y = FXSYS_round(device_y_f);
766 #endif // PDF_ENABLE_XFA
767 }
768
769 DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_Create(int width,
770 int height,
771 int alpha) {
772 std::unique_ptr<CFX_DIBitmap> pBitmap(new CFX_DIBitmap);
773 if (!pBitmap->Create(width, height, alpha ? FXDIB_Argb : FXDIB_Rgb32)) {
774 return NULL;
775 }
776 return pBitmap.release();
777 }
778
779 DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_CreateEx(int width,
780 int height,
781 int format,
782 void* first_scan,
783 int stride) {
784 FXDIB_Format fx_format;
785 switch (format) {
786 case FPDFBitmap_Gray:
787 fx_format = FXDIB_8bppRgb;
788 break;
789 case FPDFBitmap_BGR:
790 fx_format = FXDIB_Rgb;
791 break;
792 case FPDFBitmap_BGRx:
793 fx_format = FXDIB_Rgb32;
794 break;
795 case FPDFBitmap_BGRA:
796 fx_format = FXDIB_Argb;
797 break;
798 default:
799 return NULL;
800 }
801 CFX_DIBitmap* pBitmap = new CFX_DIBitmap;
802 pBitmap->Create(width, height, fx_format, (uint8_t*)first_scan, stride);
803 return pBitmap;
804 }
805
806 DLLEXPORT void STDCALL FPDFBitmap_FillRect(FPDF_BITMAP bitmap,
807 int left,
808 int top,
809 int width,
810 int height,
811 FPDF_DWORD color) {
812 if (!bitmap)
813 return;
814 #ifdef _SKIA_SUPPORT_
815 CFX_SkiaDevice device;
816 #else
817 CFX_FxgeDevice device;
818 #endif
819 device.Attach((CFX_DIBitmap*)bitmap);
820 if (!((CFX_DIBitmap*)bitmap)->HasAlpha())
821 color |= 0xFF000000;
822 FX_RECT rect(left, top, left + width, top + height);
823 device.FillRect(&rect, color);
824 }
825
826 DLLEXPORT void* STDCALL FPDFBitmap_GetBuffer(FPDF_BITMAP bitmap) {
827 return bitmap ? ((CFX_DIBitmap*)bitmap)->GetBuffer() : nullptr;
828 }
829
830 DLLEXPORT int STDCALL FPDFBitmap_GetWidth(FPDF_BITMAP bitmap) {
831 return bitmap ? ((CFX_DIBitmap*)bitmap)->GetWidth() : 0;
832 }
833
834 DLLEXPORT int STDCALL FPDFBitmap_GetHeight(FPDF_BITMAP bitmap) {
835 return bitmap ? ((CFX_DIBitmap*)bitmap)->GetHeight() : 0;
836 }
837
838 DLLEXPORT int STDCALL FPDFBitmap_GetStride(FPDF_BITMAP bitmap) {
839 return bitmap ? ((CFX_DIBitmap*)bitmap)->GetPitch() : 0;
840 }
841
842 DLLEXPORT void STDCALL FPDFBitmap_Destroy(FPDF_BITMAP bitmap) {
843 delete (CFX_DIBitmap*)bitmap;
844 }
845
846 void FPDF_RenderPage_Retail(CRenderContext* pContext,
847 FPDF_PAGE page,
848 int start_x,
849 int start_y,
850 int size_x,
851 int size_y,
852 int rotate,
853 int flags,
854 FX_BOOL bNeedToRestore,
855 IFSDK_PAUSE_Adapter* pause) {
856 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
857 if (!pPage)
858 return;
859
860 if (!pContext->m_pOptions)
861 pContext->m_pOptions = new CPDF_RenderOptions;
862
863 if (flags & FPDF_LCD_TEXT)
864 pContext->m_pOptions->m_Flags |= RENDER_CLEARTYPE;
865 else
866 pContext->m_pOptions->m_Flags &= ~RENDER_CLEARTYPE;
867 if (flags & FPDF_NO_NATIVETEXT)
868 pContext->m_pOptions->m_Flags |= RENDER_NO_NATIVETEXT;
869 if (flags & FPDF_RENDER_LIMITEDIMAGECACHE)
870 pContext->m_pOptions->m_Flags |= RENDER_LIMITEDIMAGECACHE;
871 if (flags & FPDF_RENDER_FORCEHALFTONE)
872 pContext->m_pOptions->m_Flags |= RENDER_FORCE_HALFTONE;
873 #ifndef PDF_ENABLE_XFA
874 if (flags & FPDF_RENDER_NO_SMOOTHTEXT)
875 pContext->m_pOptions->m_Flags |= RENDER_NOTEXTSMOOTH;
876 if (flags & FPDF_RENDER_NO_SMOOTHIMAGE)
877 pContext->m_pOptions->m_Flags |= RENDER_NOIMAGESMOOTH;
878 if (flags & FPDF_RENDER_NO_SMOOTHPATH)
879 pContext->m_pOptions->m_Flags |= RENDER_NOPATHSMOOTH;
880 #endif // PDF_ENABLE_XFA
881 // Grayscale output
882 if (flags & FPDF_GRAYSCALE) {
883 pContext->m_pOptions->m_ColorMode = RENDER_COLOR_GRAY;
884 pContext->m_pOptions->m_ForeColor = 0;
885 pContext->m_pOptions->m_BackColor = 0xffffff;
886 }
887 const CPDF_OCContext::UsageType usage =
888 (flags & FPDF_PRINTING) ? CPDF_OCContext::Print : CPDF_OCContext::View;
889 pContext->m_pOptions->m_AddFlags = flags >> 8;
890 pContext->m_pOptions->m_pOCContext =
891 new CPDF_OCContext(pPage->m_pDocument, usage);
892
893 CFX_Matrix matrix;
894 pPage->GetDisplayMatrix(matrix, start_x, start_y, size_x, size_y, rotate);
895
896 pContext->m_pDevice->SaveState();
897 pContext->m_pDevice->SetClip_Rect(
898 FX_RECT(start_x, start_y, start_x + size_x, start_y + size_y));
899
900 pContext->m_pContext = new CPDF_RenderContext(pPage);
901 pContext->m_pContext->AppendLayer(pPage, &matrix);
902
903 if (flags & FPDF_ANNOT) {
904 pContext->m_pAnnots = new CPDF_AnnotList(pPage);
905 FX_BOOL bPrinting = pContext->m_pDevice->GetDeviceClass() != FXDC_DISPLAY;
906 pContext->m_pAnnots->DisplayAnnots(pPage, pContext->m_pContext, bPrinting,
907 &matrix, TRUE, NULL);
908 }
909
910 pContext->m_pRenderer = new CPDF_ProgressiveRenderer(
911 pContext->m_pContext, pContext->m_pDevice, pContext->m_pOptions);
912 pContext->m_pRenderer->Start(pause);
913 if (bNeedToRestore)
914 pContext->m_pDevice->RestoreState();
915 }
916
917 DLLEXPORT int STDCALL FPDF_GetPageSizeByIndex(FPDF_DOCUMENT document,
918 int page_index,
919 double* width,
920 double* height) {
921 UnderlyingDocumentType* pDoc = UnderlyingFromFPDFDocument(document);
922 if (!pDoc)
923 return FALSE;
924
925 #ifdef PDF_ENABLE_XFA
926 int count = pDoc->GetPageCount();
927 if (page_index < 0 || page_index >= count)
928 return FALSE;
929 CPDFXFA_Page* pPage = pDoc->GetPage(page_index);
930 if (!pPage)
931 return FALSE;
932 *width = pPage->GetPageWidth();
933 *height = pPage->GetPageHeight();
934 #else // PDF_ENABLE_XFA
935 CPDF_Dictionary* pDict = pDoc->GetPage(page_index);
936 if (!pDict)
937 return FALSE;
938 CPDF_Page page;
939 page.Load(pDoc, pDict);
940 *width = page.GetPageWidth();
941 *height = page.GetPageHeight();
942 #endif // PDF_ENABLE_XFA
943
944 return TRUE;
945 }
946
947 DLLEXPORT FPDF_BOOL STDCALL
948 FPDF_VIEWERREF_GetPrintScaling(FPDF_DOCUMENT document) {
949 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
950 if (!pDoc)
951 return TRUE;
952 CPDF_ViewerPreferences viewRef(pDoc);
953 return viewRef.PrintScaling();
954 }
955
956 DLLEXPORT int STDCALL FPDF_VIEWERREF_GetNumCopies(FPDF_DOCUMENT document) {
957 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
958 if (!pDoc)
959 return 1;
960 CPDF_ViewerPreferences viewRef(pDoc);
961 return viewRef.NumCopies();
962 }
963
964 DLLEXPORT FPDF_PAGERANGE STDCALL
965 FPDF_VIEWERREF_GetPrintPageRange(FPDF_DOCUMENT document) {
966 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
967 if (!pDoc)
968 return NULL;
969 CPDF_ViewerPreferences viewRef(pDoc);
970 return viewRef.PrintPageRange();
971 }
972
973 DLLEXPORT FPDF_DUPLEXTYPE STDCALL
974 FPDF_VIEWERREF_GetDuplex(FPDF_DOCUMENT document) {
975 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
976 if (!pDoc)
977 return DuplexUndefined;
978 CPDF_ViewerPreferences viewRef(pDoc);
979 CFX_ByteString duplex = viewRef.Duplex();
980 if ("Simplex" == duplex)
981 return Simplex;
982 if ("DuplexFlipShortEdge" == duplex)
983 return DuplexFlipShortEdge;
984 if ("DuplexFlipLongEdge" == duplex)
985 return DuplexFlipLongEdge;
986 return DuplexUndefined;
987 }
988
989 DLLEXPORT FPDF_DWORD STDCALL FPDF_CountNamedDests(FPDF_DOCUMENT document) {
990 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
991 if (!pDoc)
992 return 0;
993
994 CPDF_Dictionary* pRoot = pDoc->GetRoot();
995 if (!pRoot)
996 return 0;
997
998 CPDF_NameTree nameTree(pDoc, "Dests");
999 pdfium::base::CheckedNumeric<FPDF_DWORD> count = nameTree.GetCount();
1000 CPDF_Dictionary* pDest = pRoot->GetDictBy("Dests");
1001 if (pDest)
1002 count += pDest->GetCount();
1003
1004 if (!count.IsValid())
1005 return 0;
1006
1007 return count.ValueOrDie();
1008 }
1009
1010 DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDestByName(FPDF_DOCUMENT document,
1011 FPDF_BYTESTRING name) {
1012 if (!name || name[0] == 0)
1013 return nullptr;
1014
1015 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
1016 if (!pDoc)
1017 return nullptr;
1018
1019 CPDF_NameTree name_tree(pDoc, "Dests");
1020 return name_tree.LookupNamedDest(pDoc, name);
1021 }
1022
1023 #ifdef PDF_ENABLE_XFA
1024 FPDF_RESULT FPDF_BStr_Init(FPDF_BSTR* str) {
1025 if (!str)
1026 return -1;
1027
1028 FXSYS_memset(str, 0, sizeof(FPDF_BSTR));
1029 return 0;
1030 }
1031
1032 FPDF_RESULT FPDF_BStr_Set(FPDF_BSTR* str, FPDF_LPCSTR bstr, int length) {
1033 if (!str)
1034 return -1;
1035 if (!bstr || !length)
1036 return -1;
1037 if (length == -1)
1038 length = FXSYS_strlen(bstr);
1039
1040 if (length == 0) {
1041 if (str->str) {
1042 FX_Free(str->str);
1043 str->str = NULL;
1044 }
1045 str->len = 0;
1046 return 0;
1047 }
1048
1049 if (str->str && str->len < length)
1050 str->str = FX_Realloc(char, str->str, length + 1);
1051 else if (!str->str)
1052 str->str = FX_Alloc(char, length + 1);
1053
1054 str->str[length] = 0;
1055 if (str->str == NULL)
1056 return -1;
1057
1058 FXSYS_memcpy(str->str, bstr, length);
1059 str->len = length;
1060
1061 return 0;
1062 }
1063
1064 FPDF_RESULT FPDF_BStr_Clear(FPDF_BSTR* str) {
1065 if (!str)
1066 return -1;
1067
1068 if (str->str) {
1069 FX_Free(str->str);
1070 str->str = NULL;
1071 }
1072 str->len = 0;
1073 return 0;
1074 }
1075 #endif // PDF_ENABLE_XFA
1076
1077 DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDest(FPDF_DOCUMENT document,
1078 int index,
1079 void* buffer,
1080 long* buflen) {
1081 if (!buffer)
1082 *buflen = 0;
1083
1084 if (index < 0)
1085 return nullptr;
1086
1087 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
1088 if (!pDoc)
1089 return nullptr;
1090
1091 CPDF_Dictionary* pRoot = pDoc->GetRoot();
1092 if (!pRoot)
1093 return nullptr;
1094
1095 CPDF_Object* pDestObj = nullptr;
1096 CFX_ByteString bsName;
1097 CPDF_NameTree nameTree(pDoc, "Dests");
1098 int count = nameTree.GetCount();
1099 if (index >= count) {
1100 CPDF_Dictionary* pDest = pRoot->GetDictBy("Dests");
1101 if (!pDest)
1102 return nullptr;
1103
1104 pdfium::base::CheckedNumeric<int> checked_count = count;
1105 checked_count += pDest->GetCount();
1106 if (!checked_count.IsValid() || index >= checked_count.ValueOrDie())
1107 return nullptr;
1108
1109 index -= count;
1110 int i = 0;
1111 for (const auto& it : *pDest) {
1112 bsName = it.first;
1113 pDestObj = it.second;
1114 if (!pDestObj)
1115 continue;
1116 if (i == index)
1117 break;
1118 i++;
1119 }
1120 } else {
1121 pDestObj = nameTree.LookupValue(index, bsName);
1122 }
1123 if (!pDestObj)
1124 return nullptr;
1125 if (CPDF_Dictionary* pDict = pDestObj->AsDictionary()) {
1126 pDestObj = pDict->GetArrayBy("D");
1127 if (!pDestObj)
1128 return nullptr;
1129 }
1130 if (!pDestObj->IsArray())
1131 return nullptr;
1132
1133 CFX_WideString wsName = PDF_DecodeText(bsName);
1134 CFX_ByteString utf16Name = wsName.UTF16LE_Encode();
1135 unsigned int len = utf16Name.GetLength();
1136 if (!buffer) {
1137 *buflen = len;
1138 } else if (*buflen >= len) {
1139 memcpy(buffer, utf16Name.c_str(), len);
1140 *buflen = len;
1141 } else {
1142 *buflen = -1;
1143 }
1144 return (FPDF_DEST)pDestObj;
1145 }
OLDNEW
« no previous file with comments | « fpdfsdk/src/fpdftext_embeddertest.cpp ('k') | fpdfsdk/src/fpdfview_c_api_test.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698