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/fpdf_progressive.h"
8 
9 #include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
10 #include "core/fpdfapi/fpdf_render/include/cpdf_progressiverenderer.h"
11 #include "core/fxge/include/fx_ge.h"
12 #include "fpdfsdk/include/fsdk_define.h"
13 #include "fpdfsdk/include/fsdk_rendercontext.h"
14 #include "public/fpdfview.h"
15 
16 // These checks are here because core/ and public/ cannot depend on each other.
17 static_assert(CPDF_ProgressiveRenderer::Ready == FPDF_RENDER_READER,
18               "CPDF_ProgressiveRenderer::Ready value mismatch");
19 static_assert(CPDF_ProgressiveRenderer::ToBeContinued ==
20                   FPDF_RENDER_TOBECOUNTINUED,
21               "CPDF_ProgressiveRenderer::ToBeContinued value mismatch");
22 static_assert(CPDF_ProgressiveRenderer::Done == FPDF_RENDER_DONE,
23               "CPDF_ProgressiveRenderer::Done value mismatch");
24 static_assert(CPDF_ProgressiveRenderer::Failed == FPDF_RENDER_FAILED,
25               "CPDF_ProgressiveRenderer::Failed value mismatch");
26 
FPDF_RenderPageBitmap_Start(FPDF_BITMAP bitmap,FPDF_PAGE page,int start_x,int start_y,int size_x,int size_y,int rotate,int flags,IFSDK_PAUSE * pause)27 DLLEXPORT int STDCALL FPDF_RenderPageBitmap_Start(FPDF_BITMAP bitmap,
28                                                   FPDF_PAGE page,
29                                                   int start_x,
30                                                   int start_y,
31                                                   int size_x,
32                                                   int size_y,
33                                                   int rotate,
34                                                   int flags,
35                                                   IFSDK_PAUSE* pause) {
36   if (!bitmap || !pause || pause->version != 1)
37     return FPDF_RENDER_FAILED;
38 
39   CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
40   if (!pPage)
41     return FPDF_RENDER_FAILED;
42 
43   CRenderContext* pContext = new CRenderContext;
44   pPage->SetRenderContext(std::unique_ptr<CFX_Deletable>(pContext));
45   CFX_FxgeDevice* pDevice = new CFX_FxgeDevice;
46   pContext->m_pDevice = pDevice;
47   CFX_DIBitmap* pBitmap = CFXBitmapFromFPDFBitmap(bitmap);
48   pDevice->Attach(pBitmap, !!(flags & FPDF_REVERSE_BYTE_ORDER), nullptr, false);
49 
50   IFSDK_PAUSE_Adapter IPauseAdapter(pause);
51   FPDF_RenderPage_Retail(pContext, page, start_x, start_y, size_x, size_y,
52                          rotate, flags, FALSE, &IPauseAdapter);
53 
54   if (pContext->m_pRenderer) {
55     return CPDF_ProgressiveRenderer::ToFPDFStatus(
56         pContext->m_pRenderer->GetStatus());
57   }
58   return FPDF_RENDER_FAILED;
59 }
60 
FPDF_RenderPage_Continue(FPDF_PAGE page,IFSDK_PAUSE * pause)61 DLLEXPORT int STDCALL FPDF_RenderPage_Continue(FPDF_PAGE page,
62                                                IFSDK_PAUSE* pause) {
63   if (!pause || pause->version != 1)
64     return FPDF_RENDER_FAILED;
65 
66   CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
67   if (!pPage)
68     return FPDF_RENDER_FAILED;
69 
70   CRenderContext* pContext =
71       static_cast<CRenderContext*>(pPage->GetRenderContext());
72   if (pContext && pContext->m_pRenderer) {
73     IFSDK_PAUSE_Adapter IPauseAdapter(pause);
74     pContext->m_pRenderer->Continue(&IPauseAdapter);
75     return CPDF_ProgressiveRenderer::ToFPDFStatus(
76         pContext->m_pRenderer->GetStatus());
77   }
78   return FPDF_RENDER_FAILED;
79 }
80 
FPDF_RenderPage_Close(FPDF_PAGE page)81 DLLEXPORT void STDCALL FPDF_RenderPage_Close(FPDF_PAGE page) {
82   CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
83   if (!pPage)
84     return;
85 
86   CRenderContext* pContext =
87       static_cast<CRenderContext*>(pPage->GetRenderContext());
88   if (!pContext)
89     return;
90 
91   pContext->m_pDevice->RestoreState(false);
92   pPage->SetRenderContext(std::unique_ptr<CFX_Deletable>());
93 }
94